{"id":"CVE-2026-28492","aliases":["GHSA-mr74-928f-rw69","GO-2026-4585"],"url":"https://o3.security/vulnerability/CVE-2026-28492","summary":"File Browser: Path Traversal in Public Share Links Exposes Files Outside Shared Directory","details":"### Summary\nWhen 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.\n\n### Details\nIn `http/public.go` lines 52-64, the `withHashFile` function handles public share link requests:\n\n```go\nbasePath := link.Path    // e.g. \"/documents/shared\"\nfilePath := \"\"\n\nif file.IsDir {\n    basePath = filepath.Dir(basePath)  // BUG: becomes \"/documents\" (parent!)\n    filePath = ifPath\n}\n\nd.user.Fs = afero.NewBasePathFs(d.user.Fs, basePath)\n```\n\nWhen 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/`.\n\nThis affects both `publicShareHandler` (directory listing via `/api/public/share/{hash}`) and `publicDlHandler` (file download via `/api/public/dl/{hash}/path`).\n\n### PoC\n\n1. Set up filebrowser with a user whose scope contains:\n2.    - `/documents/shared/public-file.txt` (intended to be shared)\n3.    - `/documents/secrets/passwords.txt` (NOT intended to be shared)\n4.    - `/documents/private/financial.csv` (NOT intended to be shared)\n2. Create a public share link for the directory `/documents/shared` (via POST `/api/share/documents/shared`)\n3. Access the share link: `GET /api/public/share/{hash}`\n4.    - **Expected**: Lists only contents of `/documents/shared/`\n5.    - **Actual**: Lists contents of `/documents/` (parent), revealing `secrets/`, `private/`, and `shared/` directories\n4. Download sibling files: `GET /api/public/dl/{hash}/secrets/passwords.txt`\n5.    - **Expected**: 404 or 403 (file outside share scope)\n6.    - **Actual**: 200 with file contents (sibling file downloaded successfully)\n**Standalone Go test** reproducing the exact vulnerable code path with `afero.NewBasePathFs`:\n\n```go\nfunc TestShareScopeEscape(t *testing.T) {\n    baseFs := afero.NewMemMapFs()\n    afero.WriteFile(baseFs, \"/documents/shared/public.txt\", []byte(\"public\"), 0644)\n    afero.WriteFile(baseFs, \"/documents/secrets/passwords.txt\", []byte(\"admin:hunter2\"), 0644)\n\n    linkPath := \"/documents/shared\"\n    basePath := filepath.Dir(linkPath) // BUG: \"/documents\"\n    scopedFs := afero.NewBasePathFs(baseFs, basePath)\n\n    // Sibling file is accessible through the share:\n    f, err := scopedFs.Open(\"/secrets/passwords.txt\")\n    // err is nil - file accessible! Content: \"admin:hunter2\"\n}\n```\n\nThis test passes, confirming the vulnerability.\n\n### Impact\n\n**Unauthenticated information disclosure (CWE-200, CWE-706)**. Anyone with a public share link for a directory can:\n- Browse all sibling directories and files of the shared directory\n- - Download any file within the parent directory scope\n- - This works without authentication (public shares) or after providing the share password (password-protected shares)\nAll filebrowser v2.x installations that use directory sharing are affected.\n\n### Recommended Fix\n\nRemove the `filepath.Dir()` call and use `link.Path` directly as the `BasePathFs` root:\n\n```go\nif file.IsDir {\n    // Don't change basePath - keep it as link.Path\n    filePath = ifPath\n}\nd.user.Fs = afero.NewBasePathFs(d.user.Fs, basePath)\n```\n\n**Affected commit**: e3d00d591b567a8bfe3b02e42ba586859002c77d (latest)\n**File**: `http/public.go`, line 59","published":"2026-03-05T21:06:21.185Z","modified":"2026-08-12T03:51:36.369864941Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"github.com/filebrowser/filebrowser/v2","fixedVersion":"2.61.0"}],"fix":{"url":"https://github.com/filebrowser/filebrowser/commit/31194fb57a5b92e7155219d7ec7273028fcb2e83","label":"filebrowser/filebrowser@31194fb"},"references":[{"type":"WEB","url":"https://github.com/filebrowser/filebrowser/releases/tag/v2.61.0"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/28xxx/CVE-2026-28492.json"},{"type":"ADVISORY","url":"https://github.com/filebrowser/filebrowser/security/advisories/GHSA-mr74-928f-rw69"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-28492"},{"type":"FIX","url":"https://github.com/filebrowser/filebrowser/commit/31194fb57a5b92e7155219d7ec7273028fcb2e83"},{"type":"PACKAGE","url":"https://github.com/filebrowser/filebrowser"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:36.369864941Z"}}