CVE-2026-116682
FileBrowser Quantum: Symlink following escapes user scope allowing arbitrary file read outside the served directory
FileBrowser Quantum is a free, self-hosted, web-based file manager. Prior to 1.5.2-stable and 2.0.1-beta, file read handling in backend/pkg/indexing/indexingFiles.go resolves symbolic links through GetRealPath without confirming that the resolved target remains inside the source root and the user's authorized scope. Download, preview, media, OnlyOffice, and public-share read flows that enable FollowSymlinks can therefore serve an out-of-scope target through a reachable in-scope symlink. An authenticated user with download access can read server-accessible files outside the assigned scope, and a holder of a public share link can do the same without an account when the shared directory exposes such a symlink. This issue is fixed in 1.5.2-stable and 2.0.1-beta.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.6
FileBrowser Quantum: Symlink following escapes user scope allowing arbitrary file read outside the served directory
FileBrowser Quantum is a free, self-hosted, web-based file manager. Prior to 1.5.2-stable and 2.0.1-beta, file read handling in backend/pkg/indexing/indexingFiles.go resolves symbolic links through GetRealPath without confirming that the resolved target remains inside the source root and the user's authorized scope. Download, preview, media, OnlyOffice, and public-share read flows that enable FollowSymlinks can therefore serve an out-of-scope target through a reachable in-scope symlink. An authenticated user with download access can read server-accessible files outside the assigned scope, and a holder of a public share link can do the same without an account when the shared directory exposes such a symlink. This issue is fixed in 1.5.2-stable and 2.0.1-beta.
- Record
CVE-2026-116682- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-22, CWE-59
- Updated
- 2026-11-02
EUVDEUVD-2026-111279
8.6
FileBrowser Quantum is a free, self-hosted, web-based file manager. Prior to 1.5.2-stable and 2.0.1-beta, file read handling in backend/pkg/indexing/indexingFiles.go resolves symbolic links through GetRealPath without confirming that the resolved target remains inside the source root and the user's authorized scope. Download, preview, media, OnlyOffice, and public-share read flows that enable FollowSymlinks can therefore serve an out-of-scope target through a reachable in-scope symlink. An authenticated user with download access can read server-accessible files outside the assigned scope, and a holder of a public share link can do the same without an account when the shared directory exposes such a symlink. This issue is fixed in 1.5.2-stable and 2.0.1-beta.
- Record
EUVD-2026-111279- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Updated
- 2026-11-03
GitHub AdvisoriesGHSA-mgqf-5mf5-prfj
8.6
FileBrowser: Symlink following escapes user scope allowing arbitrary file read outside the served directory
Summary
File read paths resolve symbolic links with filepath.EvalSymlinks and then operate on the resolved target without re-checking that the target still lies inside the user's source/scope.
A symlink located inside a user's accessible directory that points outside the scope (for example to /etc/passwd, another tenant's directory, SSH keys, or container secrets) is followed transparently, and its contents are served through the normal download, preview, media, and OnlyOffice endpoints. Any authenticated user with download access can read files anywhere the server process can, whenever such a symlink is reachable in their scope.
The same symlink-following read path is used by the public share endpoints, which are authorized only by a share hash and not by any account, so when a public share exposes a directory that contains such a symlink, an unauthenticated attacker holding only the share link reads files outside the scope with no credential.
Details
1. Symlink resolution performs no containment check (indexing/iteminfo/utils.go:110-119)
func ResolveSymlinks(path string) (string, bool, error) {
resolvedPath, err := filepath.EvalSymlinks(path) // follows the link to its real target
if err != nil {
return path, false, fmt.Errorf("could not resolve symlinks for %s: %v", path, err)
}
info, err := os.Lstat(resolvedPath)
// ...
return resolvedPath, IsDirectory(info), nil // returned with no scope validation
}
There is no comparison of resolvedPath against the index/scope root.
2. GetRealPath returns the resolved target unchecked (indexing/indexingFiles.go:991-1008)
absolutePath, err := filepath.Abs(joinedPath)
// ...
realPath, isDir, err := iteminfo.ResolveSymlinks(absolutePath) // escapes scope here
// ...
return realPath, isDir, err
realPath is then used by file handlers to open and serve the file. No caller re-validates that realPath is a descendant of the user's source root. (By contrast, the project did add containment for archive extraction via symlinkTargetStaysUnderDest, but that guard is specific to extraction and is not applied to this general read path.)
3. The read handlers request symlink following, including the unauthenticated public-share handlers (http/resource.go:96,503, http/media.go:124, http/onlyOffice.go:133, http/public.go:279,441,494)
FollowSymlinks: true,
Authenticated download, preview, media-subtitle, and OnlyOffice read flows all set FollowSymlinks: true, and so do the public share handlers in http/public.go. The public download route is registered as publicApi.HandleFunc("GET /resources/download", withHashFile(publicDownloadHandler)) (http/httpRouter.go:130), where withHashFile authorizes by the share hash alone with no account, so the same escape is reachable with no authentication when a public share exposes a directory containing the symlink.
PoC
Confirmed live on gtstef/filebrowser:1.3.3-stable. A symlink pointing outside the user's directory must exist inside it; here it is placed on the host volume, which is what happens whenever a bind-mounted directory contains symlinks.
1. Start a fresh container and seed a file outside the user's intended subtree.
docker rm -f fb-q-lab 2>/dev/null; rm -rf /tmp/fb-q-lab; mkdir -p /tmp/fb-q-lab/srv/user1
echo "ROOT_DB_PASSWORD=supersecret" > /tmp/fb-q-lab/srv/secret-outside.txt
docker run -d --name fb-q-lab -p 8090:80 -v /tmp/fb-q-lab/srv:/srv gtstef/filebrowser:1.3.3-stable && sleep 8
TARGET_URL=http://localhost:8090
2. Place symlinks inside the served tree that point outside it. One points at a host file (/etc/passwd), one at the file outside the user's subtree.
docker exec fb-q-lab sh -c 'ln -sf /etc/passwd /srv/user1/passwd_link; ln -sf /srv/secret-outside.txt /srv/user1/secret_link'
Vector 1: authenticated user (any account with download access)
**3. Log in as the…
- Record
GHSA-mgqf-5mf5-prfj- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-22, CWE-59
- Updated
- 2026-11-02
NVD
8.6
FileBrowser Quantum is a free, self-hosted, web-based file manager. Prior to 1.5.2-stable and 2.0.1-beta, file read handling in backend/pkg/indexing/indexingFiles.go resolves symbolic links through GetRealPath without confirming that the resolved target remains inside the source root and the user's authorized scope. Download, preview, media, OnlyOffice, and public-share read flows that enable FollowSymlinks can therefore serve an out-of-scope target through a reachable in-scope symlink. An authenticated user with download access can read server-accessible files outside the assigned scope, and a holder of a public share link can do the same without an account when the shared directory exposes such a symlink. This issue is fixed in 1.5.2-stable and 2.0.1-beta.
- Record
CVE-2026-116682- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-22, CWE-59
- Updated
- 2026-11-03
OSV
8.6
FileBrowser Quantum: Symlink following escapes user scope allowing arbitrary file read outside the served directory
FileBrowser Quantum is a free, self-hosted, web-based file manager. Prior to 1.5.2-stable and 2.0.1-beta, file read handling in backend/pkg/indexing/indexingFiles.go resolves symbolic links through GetRealPath without confirming that the resolved target remains inside the source root and the user's authorized scope. Download, preview, media, OnlyOffice, and public-share read flows that enable FollowSymlinks can therefore serve an out-of-scope target through a reachable in-scope symlink. An authenticated user with download access can read server-accessible files outside the assigned scope, and a holder of a public share link can do the same without an account when the shared directory exposes such a symlink. This issue is fixed in 1.5.2-stable and 2.0.1-beta.
- Record
CVE-2026-116682- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-22, CWE-59
- Updated
- 2026-11-06
OSVGHSA-mgqf-5mf5-prfj
8.6
FileBrowser: Symlink following escapes user scope allowing arbitrary file read outside the served directory
Summary
File read paths resolve symbolic links with filepath.EvalSymlinks and then operate on the resolved target without re-checking that the target still lies inside the user's source/scope.
A symlink located inside a user's accessible directory that points outside the scope (for example to /etc/passwd, another tenant's directory, SSH keys, or container secrets) is followed transparently, and its contents are served through the normal download, preview, media, and OnlyOffice endpoints. Any authenticated user with download access can read files anywhere the server process can, whenever such a symlink is reachable in their scope.
The same symlink-following read path is used by the public share endpoints, which are authorized only by a share hash and not by any account, so when a public share exposes a directory that contains such a symlink, an unauthenticated attacker holding only the share link reads files outside the scope with no credential.
Details
1. Symlink resolution performs no containment check (indexing/iteminfo/utils.go:110-119)
func ResolveSymlinks(path string) (string, bool, error) {
resolvedPath, err := filepath.EvalSymlinks(path) // follows the link to its real target
if err != nil {
return path, false, fmt.Errorf("could not resolve symlinks for %s: %v", path, err)
}
info, err := os.Lstat(resolvedPath)
// ...
return resolvedPath, IsDirectory(info), nil // returned with no scope validation
}
There is no comparison of resolvedPath against the index/scope root.
2. GetRealPath returns the resolved target unchecked (indexing/indexingFiles.go:991-1008)
absolutePath, err := filepath.Abs(joinedPath)
// ...
realPath, isDir, err := iteminfo.ResolveSymlinks(absolutePath) // escapes scope here
// ...
return realPath, isDir, err
realPath is then used by file handlers to open and serve the file. No caller re-validates that realPath is a descendant of the user's source root. (By contrast, the project did add containment for archive extraction via symlinkTargetStaysUnderDest, but that guard is specific to extraction and is not applied to this general read path.)
3. The read handlers request symlink following, including the unauthenticated public-share handlers (http/resource.go:96,503, http/media.go:124, http/onlyOffice.go:133, http/public.go:279,441,494)
FollowSymlinks: true,
Authenticated download, preview, media-subtitle, and OnlyOffice read flows all set FollowSymlinks: true, and so do the public share handlers in http/public.go. The public download route is registered as publicApi.HandleFunc("GET /resources/download", withHashFile(publicDownloadHandler)) (http/httpRouter.go:130), where withHashFile authorizes by the share hash alone with no account, so the same escape is reachable with no authentication when a public share exposes a directory containing the symlink.
PoC
Confirmed live on gtstef/filebrowser:1.3.3-stable. A symlink pointing outside the user's directory must exist inside it; here it is placed on the host volume, which is what happens whenever a bind-mounted directory contains symlinks.
1. Start a fresh container and seed a file outside the user's intended subtree.
docker rm -f fb-q-lab 2>/dev/null; rm -rf /tmp/fb-q-lab; mkdir -p /tmp/fb-q-lab/srv/user1
echo "ROOT_DB_PASSWORD=supersecret" > /tmp/fb-q-lab/srv/secret-outside.txt
docker run -d --name fb-q-lab -p 8090:80 -v /tmp/fb-q-lab/srv:/srv gtstef/filebrowser:1.3.3-stable && sleep 8
TARGET_URL=http://localhost:8090
2. Place symlinks inside the served tree that point outside it. One points at a host file (/etc/passwd), one at the file outside the user's subtree.
docker exec fb-q-lab sh -c 'ln -sf /etc/passwd /srv/user1/passwd_link; ln -sf /srv/secret-outside.txt /srv/user1/secret_link'
Vector 1: authenticated user (any account with download access)
**3. Log in as the…
- Record
GHSA-mgqf-5mf5-prfj- CVSS 3.1
- 8.6 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N - Weakness
- CWE-22, CWE-59
- Updated
- 2026-11-06
OSVGO-2026-6870 No score
FileBrowser: Symlink following escapes user scope allowing arbitrary file read outside the served directory in github.com/gtsteffaniak/filebrowser/backend
FileBrowser: Symlink following escapes user scope allowing arbitrary file read outside the served directory in github.com/gtsteffaniak/filebrowser/backend
- Record
GO-2026-6870- Updated
- 2026-11-06
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/gtsteffaniak/filebrowser/backendGo |
before 0.0.0-20260814233832-4126edeb07a0 | 0.0.0-20260814233832-4126edeb07a0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases | OSV | |
| facts | EUVD, NVD, OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-116682 is a high vulnerability (CVSS 8.6) in Gtsteffaniak Filebrowser, published October 27, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.54%, the 45th percentile. Fixed in github.com/gtsteffaniak/filebrowser/backend 0.0.0-20260814233832-4126edeb07a0.
References
github.com/gtsteffaniak/filebrowser/security/advisories/GHSA-mgqf-5mf5-prfj
github.com/gtsteffaniak/filebrowser/pull/2795
github.com/gtsteffaniak/filebrowser/pull/2800
github.com/gtsteffaniak/filebrowser/commit/3c8c02414eefd3351ffe437fa39ff6eb150ffa67
github.com/gtsteffaniak/filebrowser/commit/4126edeb07a015c3809a89249b283e07a4e50c38
github.com/gtsteffaniak/filebrowser/releases/tag/v1.5.2-stable
Left out here: the rest of 2 source descriptions. The JSON record has them.