NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
MEDIUM severity

CVE-2026-32758 — filebrowser

MEDIUMFix: filebrowser/filebrowser@4bd7d69

CVE-2026-32758 is a medium-severity (CVSS 6.5) Path Traversal vulnerability in github.com/filebrowser/filebrowser/v2. A fix is available for github.com/filebrowser/filebrowser/v2 — see the affected versions and patch details below.

File Browser has an Access Rule Bypass via Path Traversal in Copy/Rename Destination Parameter

Also known asGHSA-9f3r-2vgw-m8xpGO-2026-4711
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 6, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-32758.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk+0.01%
Lower risk than most CVEs35th percentile — riskier than 35% of all scored CVEsHighest risk
0.00%0.31%0.63%0.94%0.0%0.4%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐹github.com/filebrowser/filebrowser/v2

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Description

The resourcePatchHandler in http/resource.go validates the destination path against configured access rules before the path is cleaned/normalized. The rules engine (rules/rules.go) uses literal string prefix matching (strings.HasPrefix) or regex matching against the raw path. The actual file operation (fileutils.Copy, patchAction) subsequently calls path.Clean() which resolves .. sequences, producing a different effective path than the one validated.

This allows an authenticated user with Create or Rename permissions to bypass administrator-configured deny rules by including .. (dot-dot) path traversal sequences in the destination query parameter of a PATCH request.

Steps to Reproduce

1. Verify the rule works normally

# This should return 403 Forbidden
curl -X PATCH \
  -H "X-Auth: <alice_jwt>" \
  "http://host/api/resources/public/test.txt?action=copy&destination=%2Frestricted%2Fcopied.txt"

2. Exploit the bypass

# This should succeed despite the deny rule
curl -X PATCH \
  -H "X-Auth: <alice_jwt>" \
  "http://host/api/resources/public/test.txt?action=copy&destination=%2Fpublic%2F..%2Frestricted%2Fcopied.txt"

3. Result

The file test.txt is copied to /restricted/copied.txt despite the deny rule for /restricted/.

Root Cause Analysis

In http/resource.go:209-257:

dst := r.URL.Query().Get("destination")       // line 212
dst, err := url.QueryUnescape(dst)             // line 214 — dst contains ".."
if !d.Check(src) || !d.Check(dst) {            // line 215 — CHECK ON UNCLEANED PATH
    return http.StatusForbidden, nil
}

In rules/rules.go:29-35:

func (r *Rule) Matches(path string) bool {
    if r.Regex {
        return r.Regexp.MatchString(path)      // regex on literal path
    }
    return strings.HasPrefix(path, r.Path)     // prefix on literal path
}

In fileutils/copy.go:12-17:

func Copy(afs afero.Fs, src, dst string, ...) error {
    if dst = path.Clean("/" + dst); dst == "" { // CLEANING HAPPENS HERE, AFTER CHECK
        return os.ErrNotExist
    }

The rules check sees /public/../restricted/copied.txt (no match for /restricted/ prefix). The file operation resolves it to /restricted/copied.txt (within the restricted path).

Secondary Issue

In the same handler, the error from url.QueryUnescape is checked after d.Check() runs (lines 214-220), meaning the rules check executes on a potentially malformed string if unescaping fails.

Impact

An authenticated user with Copy (Create) or Rename permission can write or move files into any path within their scope that is protected by deny rules. This bypasses both:

  • Prefix-based rules: strings.HasPrefix on uncleaned path misses the match
  • Regex-based rules: Standard patterns like ^/restricted/.* fail on uncleaned path

Cannot be used to:

  • Escape the user's BasePathFs scope (afero prevents this)
  • Read from restricted paths (GET handler uses cleaned r.URL.Path)

Suggested Fix

Clean the destination path before the rules check:

dst, err := url.QueryUnescape(dst)
if err != nil {
    return errToStatus(err), err
}
dst = path.Clean("/" + dst)
src = path.Clean("/" + src)
if !d.Check(src) || !d.Check(dst) {
    return http.StatusForbidden, nil
}
if dst == "/" || src == "/" {
    return http.StatusForbidden, nil
}

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/filebrowser/filebrowser/v2all versions2.62.0go get github.com/filebrowser/filebrowser/v2@v2.62.0

Affected Products

1 product · 1 configurations
Application
filebrowserfilebrowser
< 2.62.0
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/filebrowser/filebrowser/v2, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update github.com/filebrowser/filebrowser/v2 to 2.62.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-32758 is resolved across your whole dependency graph.

  3. Workarounds

    Resolve every user-supplied path to its canonical form and reject anything that escapes the intended directory, and run the component under an account that has no read or write access outside the directory it legitimately serves.

Frequently Asked Questions

## Description The `resourcePatchHandler` in `http/resource.go` validates the destination path against configured access rules before the path is cleaned/normalized. The rules engine (`rules/rules.go`) uses literal string prefix matching (`strings.HasPrefix`) or regex matching against the raw path. The actual file operation (`fileutils.Copy`, `patchAction`) subsequently calls `path.Clean()` which resolves `..` sequences, producing a different effective path than the one validated. This allows an authenticated user with Create or Rename permissions to bypass administrator-configured deny rule
O3 Security · Impact-Aware SCA

Is CVE-2026-32758 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2026-32758: filebrowser — Fixed in 2.62.0