GHSA-mr74-928f-rw69 CVE-2026-28492 GO-2026-4585
FileBrowser has Path Traversal in Public Share Links that Exposes Files Outside Shared Directory
- Severity
- 0.0 / 10
- Medium · CVSS 4.0
- Exploit chance (EPSS)
- 0.37%
- Chance of exploitation in the next 30 days. Higher than 31.33% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
- Fix
2.61.0- Upgrade github.com/filebrowser/filebrowser/v2 to this version or later
Description
Summary
When a user creates a public share link for a directory, the withHashFile middleware in http/public.go (line 59) uses filepath.Dir(link.Path) to compute the BasePathFs root. This sets the filesystem root to the parent directory instead of the shared directory itself, allowing anyone with the share link to browse and download files from all sibling directories.
Details
In http/public.go lines 52-64, the withHashFile function handles public share link requests:
basePath := link.Path // e.g. "/documents/shared"
filePath := ""
if file.IsDir {
basePath = filepath.Dir(basePath) // BUG: becomes "/documents" (parent!)
filePath = ifPath
}
d.user.Fs = afero.NewBasePathFs(d.user.Fs, basePath)
When a directory at /documents/shared is shared, filepath.Dir("/documents/shared") evaluates to "/documents". The BasePathFs is then rooted at the parent directory /documents/, giving the share link access to everything under /documents/ - not just the intended /documents/shared/.
This affects both publicShareHandler (directory listing via /api/public/share/{hash}) and publicDlHandler (file download via /api/public/dl/{hash}/path).
PoC
- Set up filebrowser with a user whose scope contains:
-
/documents/shared/public-file.txt(intended to be shared)
-
/documents/secrets/passwords.txt(NOT intended to be shared)
-
/documents/private/financial.csv(NOT intended to be shared)
- Create a public share link for the directory
/documents/shared(via POST/api/share/documents/shared) - Access the share link:
GET /api/public/share/{hash} -
- Expected: Lists only contents of
/documents/shared/
- Expected: Lists only contents of
-
- Actual: Lists contents of
/documents/(parent), revealingsecrets/,private/, andshared/directories
- Actual: Lists contents of
- Download sibling files:
GET /api/public/dl/{hash}/secrets/passwords.txt -
- Expected: 404 or 403 (file outside share scope)
-
- Actual: 200 with file contents (sibling file downloaded successfully)
Standalone Go test reproducing the exact vulnerable code path with
afero.NewBasePathFs:
- Actual: 200 with file contents (sibling file downloaded successfully)
Standalone Go test reproducing the exact vulnerable code path with
func TestShareScopeEscape(t *testing.T) {
baseFs := afero.NewMemMapFs()
afero.WriteFile(baseFs, "/documents/shared/public.txt", []byte("public"), 0644)
afero.WriteFile(baseFs, "/documents/secrets/passwords.txt", []byte("admin:hunter2"), 0644)
linkPath := "/documents/shared"
basePath := filepath.Dir(linkPath) // BUG: "/documents"
scopedFs := afero.NewBasePathFs(baseFs, basePath)
// Sibling file is accessible through the share:
f, err := scopedFs.Open("/secrets/passwords.txt")
// err is nil - file accessible! Content: "admin:hunter2"
}
This test passes, confirming the vulnerability.
Impact
Unauthenticated information disclosure (CWE-200, CWE-706). Anyone with a public share link for a directory can:
- Browse all sibling directories and files of the shared directory
-
- Download any file within the parent directory scope
-
- This works without authentication (public shares) or after providing the share password (password-protected shares) All filebrowser v2.x installations that use directory sharing are affected.
Recommended Fix
Remove the filepath.Dir() call and use link.Path directly as the BasePathFs root:
if file.IsDir {
// Don't change basePath - keep it as link.Path
filePath = ifPath
}
d.user.Fs = afero.NewBasePathFs(d.user.Fs, basePath)
Affected commit: e3d00d591b567a8bfe3b02e42ba586859002c77d (latest)
File: http/public.go, line 59
Affected versions
Go
| Package | Vulnerable | Fixed in |
|---|---|---|
| github.com/filebrowser/filebrowser | all versions |
No fix yet |
| github.com/filebrowser/filebrowser/v2 | < 2.61.0 |
2.61.0 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
github.com/filebrowser/filebrowser/v2 Go → 2.61.0
- go
go get github.com/filebrowser/filebrowser/v2@v2.61.0 && go mod tidy
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- None
- Privileges required
- Low
- User interaction
- None
- Confidentiality (vulnerable system)
- High
- Integrity (vulnerable system)
- None
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 6.5
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Weakness
CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
How to prevent it
- Architecture and Design: Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-833g-cqhp-h72j File Browser: Share API exposes the password hash and bypass token | Low | Also affects github.com/filebrowser/filebrowser |
| GHSA-83xp-526h-j3ww File Browser: Archive builder turns backslash filenames into path traversal (zip-slip) | Medium | Also affects github.com/filebrowser/filebrowser |
| GHSA-7rc3-g7h6-22m7 File Browser: Colliding username normalization gives two users the same home directory | High | Also affects github.com/filebrowser/filebrowser |
| GHSA-8wc8-hf36-mjh9 File Browser: ScopedFs follows a dangling symlink on write, letting a scoped user create files outside their scope | Medium | Also affects github.com/filebrowser/filebrowser |
| GHSA-fmm7-x4gx-8jhr File Browser: Out-of-scope file deletion by a Create-only scoped user via symlink-following RemoveAll in upload failure-cleanup | High | Also affects github.com/filebrowser/filebrowser |
| GHSA-xqp3-jq6g-x3qm File Browser: Authentication Bypass via Proxy Auth Header Forgery | Critical | Also affects github.com/filebrowser/filebrowser |
| GHSA-m93h-4hw7-5qcm File Browser: Command Injection via Authentication Hook Shell Substitution (Pre-Authentication RCE) | Critical | Also affects github.com/filebrowser/filebrowser |
| GHSA-8c9q-7855-wfxq File Browser has a Command Execution Allowlist Bypass via Shell Metacharacter Injection | High | Also affects github.com/filebrowser/filebrowser |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor