CVE-2026-72921: SeaweedFS Filer JWT allowed_prefixes Authorization Bypass
A filer JWT scoped to one tenant's path prefix also grants access to sibling paths that share the same string prefix, letting one tenant read or write another tenant's data.

The problem
SeaweedFS filer uses JWT tokens with an allowed_prefixes list to restrict which filer paths a token can access. Before version 4.24, the check in weed/server/filer_server_handlers.go called strings.HasPrefix on the raw request path.
Because strings.HasPrefix is a byte-level match with no concept of path separators, a token scoped to /tenant1 also passes the check for /tenant1234, /tenant1-old, /tenant1backup, and any other sibling path that begins with those characters. In a multi-tenant deployment this is a full cross-tenant read and write bypass for anyone holding a valid scoped token.
Proof of concept
A working proof-of-concept for CVE-2026-72921 in github.com/seaweedfs/seaweedfs, with the exact payload below.
# Token is issued with allowed_prefixes = ["/tenant1"]
# Attacker-controlled request targets a SIBLING path that is NOT a child of /tenant1
curl -s -H 'Authorization: Bearer <jwt_scoped_to_tenant1>' \
http://filer-host:8888/tenant1234/sensitive-data.txt
# strings.HasPrefix("/tenant1234/sensitive-data.txt", "/tenant1") == true
# => authorization passes, response is returnedThe root cause is CWE-863 (Incorrect Authorization): the guard used strings.HasPrefix(requestPath, allowedPrefix) without anchoring on a path separator. The string /tenant1 is a byte prefix of /tenant1234, so the check returns true even though the paths belong to completely different tenants.
The patch (PR #9439, commit 05ed5c9) replaced the raw prefix match with a component-aware comparison after calling path.Clean on the request path. The fixed logic checks that the cleaned path either equals the allowed prefix exactly, or starts with allowedPrefix + "/", so /tenant1 only authorizes /tenant1 itself and true descendants like /tenant1/file.txt.
The fix
Upgrade to SeaweedFS 4.24 (commit 05ed5c9ae8a2). The allowed_prefixes check now uses path.Clean normalization and matches on /-separated path components, preventing sibling-path bypass. As a short-term workaround, ensure no configured prefix is a string-prefix of another (for example, add a trailing-separator convention such as /tenant1/), but upgrading is the only reliable fix.
Reported by Kadir Arslan.
Related research
- critical · 9.8CVE-2026-72920CVE-2026-72920: SeaweedFS Unauthenticated IAM gRPC Service
- high · 7.7CVE-2026-55874CVE-2026-55874: SeaweedFS S3 Gateway Cross-Bucket Path Traversal via X-Amz-Copy-Source
- highCVE-2026-54917CVE-2026-54917: SeaweedFS Path Traversal in S3 and Iceberg REST Gateways
- critical · 9.3CVE-2026-73080CVE-2026-73080: SeaweedFS Unauthenticated SSRF via VolumeServer.FetchAndWriteNeedle