GHSA-5WW9-JG6Q-38R7
Vulnerability from github – Published: 2026-06-12 21:00 – Updated: 2026-06-12 21:00Summary
A low-privileged authenticated user of filebrowser (with create + delete permissions in their own isolated scope) can silently destroy share-link records belonging to any other user — including the administrator — by performing a legitimate DELETE on a file in their own directory whose logical path happens to be a byte-prefix of another user's stored share.Link.Path. The file contents of the victim are not exposed, but the victim's share links are irrevocably wiped.
Details
resourceDeleteHandler in http/resource.go cleans up any share records that reference a deleted file by calling:
// http/resource.go
err = d.store.Share.DeleteWithPathPrefix(file.Path)
file.Path here is the logical path from the URL of the deleting user's request (e.g. /a), not the absolute filesystem path. It is passed as-is to the bolt backend:
// storage/bolt/share.go
func (s shareBackend) DeleteWithPathPrefix(pathPrefix string) error {
var links []share.Link
if err := s.db.Prefix("Path", pathPrefix, &links); err != nil {
return err
}
for _, link := range links {
err = errors.Join(err, s.db.DeleteStruct(&share.Link{Hash: link.Hash}))
}
return err
}
Why the design contradicts this behavior. share.Link carries a UserID field and the application elsewhere treats shares as per-user owned resources. shareDeleteHandler explicitly enforces link.UserID != d.user.ID && !d.user.Perm.Admin → 403. The file-deletion side-effect path is the only location that bypasses this rule.
Impact
- Integrity: unauthorized deletion of share-link metadata belonging to arbitrary users, including administrators.
- Availability: effective denial-of-service of the share-link feature — a cooperating (or malicious) low-priv user can wipe the bulk of existing share links by iterating a short set of one- and two-character prefixes.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/filebrowser/filebrowser"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.11.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.63.5"
},
"package": {
"ecosystem": "Go",
"name": "github.com/filebrowser/filebrowser/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.63.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-54097"
],
"database_specific": {
"cwe_ids": [
"CWE-639"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-12T21:00:55Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "### Summary\nA low-privileged authenticated user of filebrowser (with `create` + `delete` permissions in their own isolated scope) can silently destroy share-link records belonging to any other user \u2014 including the administrator \u2014 by performing a legitimate DELETE on a file in their own directory whose logical path happens to be a byte-prefix of another user\u0027s stored `share.Link.Path`. The file contents of the victim are not exposed, but the victim\u0027s share links are irrevocably wiped.\n\n### Details\n`resourceDeleteHandler` in `http/resource.go` cleans up any share records that reference a deleted file by calling:\n\n```go\n// http/resource.go\nerr = d.store.Share.DeleteWithPathPrefix(file.Path)\n```\n\n`file.Path` here is the *logical* path from the URL of the deleting user\u0027s request (e.g. `/a`), not the absolute filesystem path. It is passed as-is to the bolt backend:\n\n```go\n// storage/bolt/share.go\nfunc (s shareBackend) DeleteWithPathPrefix(pathPrefix string) error {\n var links []share.Link\n if err := s.db.Prefix(\"Path\", pathPrefix, \u0026links); err != nil {\n return err\n }\n for _, link := range links {\n err = errors.Join(err, s.db.DeleteStruct(\u0026share.Link{Hash: link.Hash}))\n }\n return err\n}\n```\n**Why the design contradicts this behavior.** `share.Link` carries a `UserID` field and the application elsewhere treats shares as per-user owned resources. `shareDeleteHandler` explicitly enforces `link.UserID != d.user.ID \u0026\u0026 !d.user.Perm.Admin \u2192 403`. The file-deletion side-effect path is the only location that bypasses this rule.\n\n\n\n### Impact\n- Integrity: unauthorized deletion of share-link metadata belonging to arbitrary users, including administrators.\n- Availability: effective denial-of-service of the share-link feature \u2014 a cooperating (or malicious) low-priv user can wipe the bulk of existing share links by iterating a short set of one- and two-character prefixes.",
"id": "GHSA-5ww9-jg6q-38r7",
"modified": "2026-06-12T21:00:55Z",
"published": "2026-06-12T21:00:55Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-5ww9-jg6q-38r7"
},
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/commit/0231b7ebdfbe77a6c54027d30c4856c3fd81ee4d"
},
{
"type": "PACKAGE",
"url": "https://github.com/filebrowser/filebrowser"
},
{
"type": "WEB",
"url": "https://github.com/filebrowser/filebrowser/releases/tag/v2.63.6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "File Browser: Cross-user unauthorized share-link deletion via unbounded prefix match in DeleteWithPathPrefix"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.