Feb 10, 2026·6 min read·54 visits
A case-sensitivity flaw in File Browser's user update logic allows attackers to bypass the 'current password' requirement when changing credentials. By sending 'Password' (Title Case) instead of 'password' (lowercase) in the API request, the security check is skipped, but the password update still succeeds. Fixed in version 2.57.1.
File Browser, the beloved Swiss Army knife for self-hosted file management, suffered from a classic logic error: it forgot that 'Password' and 'password' are not the same thing in the eyes of a Go map. This vulnerability allows an authenticated user (or an attacker with a hijacked session) to change their password—or potentially others—without knowing the current password, effectively bypassing the application's account takeover protection mechanism. It's a textbook example of how a single capital letter can dismantle an entire security check.
In the world of web application security, the mechanism for changing a password is sacred ground. Standard procedure dictates that if you want to change your lock, you must first prove you have the key. This prevents a specific type of chaos: if I walk away from my laptop and leave my session open, a prankster (or adversary) shouldn't be able to lock me out of my own account by changing my password. They should hit a wall asking for the current password.
File Browser, a widely used Go-based file manager, implemented this logic. They had a list of "sensible" (sensitive) fields. If you tried to touch the password, the permissions, or the username, the gatekeeper would stop you and demand proof of ownership (the current password). It's a sound design pattern.
But here is the catch: computers are pedantic. To a human, password, Password, and PASSWORD convey the same concept. To a Go map lookup, they are three entirely different keys. CVE-2026-25889 is the story of how attackers can whisper "Password" with a capital P to walk right past the bouncer, change the locks, and take over the house.
The vulnerability hides in the userPutHandler within http/users.go. When a PUT request arrives to update a user, the application receives a JSON payload containing a list of fields the client wishes to modify. This list is stored in req.Which.
The application maintains a map called sensibleFields. This map acts as a blocklist for sensitive operations. The logic is simple: iterate through the fields the user wants to change, check if they exist in the sensibleFields map, and if they do, trigger the CheckPwd function to verify the current password.
Here is the fatal flaw: Go maps are case-sensitive. The keys in sensibleFields were stored as lowercase strings (e.g., "password"). If the incoming request specifies that it wants to update "Password" (Title Case), the map lookup sensibleFields["Password"] returns false. The application assumes the field is innocuous and skips the security check entirely.
However, the subsequent logic that actually binds the request data to the user struct and updates the database is significantly more lenient (likely due to the behavior of the JSON unmarshaler or struct tags). It happily recognizes "Password" as mapping to the User.Password struct field. The result? The check fails (allowing the request), but the update succeeds (changing the password).
Let's look at the code that caused the issue. It's a brilliant example of how a tiny assumption can lead to a CVE.
The Vulnerable Code (Before Patch):
// http/users.go
// We iterate over the fields the user wants to update
for _, field := range req.Which {
// DIRECT LOOKUP: If the exact string isn't in the map, we skip the check.
if _, ok := sensibleFields[field]; ok {
// This block only runs if 'field' matches a key exactly (e.g., "password")
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
}
}If field is "Password", ok is false. The code execution flows right past the CheckPwd block.
The Fix (Commit ff2f004):
The fix is incredibly simple: normalize the input. By forcing the field name to lowercase before checking the map, the developers ensure that "Password", "PASSWORD", and "password" all trigger the security check.
// http/users.go
import "strings"
// ...
for _, field := range req.Which {
// NORMALIZE: Downcase the field before looking it up.
if _, ok := sensibleFields[strings.ToLower(field)]; ok {
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
}
}It's a one-line change, but it makes the difference between a secure app and an account takeover vulnerability.
Exploiting this is trivial once you have an authenticated session. This could be your own account (to establish persistence if you forgot your password) or a stolen session cookie.
The Setup:
You are logged in as a standard user. You want to change your password to "Pwned!123", but you don't know the current password.
The Attack:
You intercept the PUT request to /api/users/1 (assuming your ID is 1) and modify the JSON body.
Standard Request (Blocked):
{
"which": ["password"],
"password": "Pwned!123"
}Response: 400 Bad Request - "Current password incorrect".
Exploit Request (Bypass):
{
"which": ["Password"],
"password": "Pwned!123"
}Note the capital 'P' in the 'which' array.
The Outcome:
"Password" from req.Which.sensibleFields["Password"]. Result: nil/false.password value (or even Password in the data object) to the user struct.Congratulations, you have just changed the lock without the key.
While this vulnerability requires authentication (CVSS 5.4), do not underestimate it. In an enterprise or homelab environment, "Authentication" is often just one XSS away.
If an attacker manages to hijack a session cookie (perhaps via a separate XSS vulnerability or by sniffing traffic on non-HTTPS connections), they typically have access only for the duration of that session. Standard security practice allows the victim to revoke sessions or simply wait for them to expire.
With CVE-2026-25889, a session hijack becomes a permanent Account Takeover (ATO). The attacker uses the temporary session to change the victim's password. Now, even if the victim realizes something is wrong, they cannot log back in. The attacker owns the account permanently.
Furthermore, if an admin account is compromised, this flaw allows the attacker to change the passwords of other users (if the admin interface uses the same endpoint logic) without needing the admin's current password again, facilitating lateral movement across the file system.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
File Browser filebrowser | < 2.57.1 | 2.57.1 |
| Attribute | Detail |
|---|---|
| CVE ID | CVE-2026-25889 |
| CVSS | 5.4 (Medium) |
| CWE | CWE-178 (Improper Handling of Case Sensitivity) |
| Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N |
| Attack Vector | Network (API) |
| Patch Commit | ff2f00498cff151e2fb1f5f0b16963bf33c3d6d4 |
The software does not properly handle case sensitivity when processing sensitive information, leading to inconsistent application of security controls.
Docling prior to version 2.131.0 is vulnerable to arbitrary local code execution during module initialization due to incorrect order of operations in its plugin discovery system. Even when the default option to reject external plugins is active, Docling utilizes Pluggy to scan and import entrypoints before performing namespace validation.
An uncontrolled resource consumption vulnerability exists in the Docling document conversion library. Maliciously structured HTML, JATS, ODS, or BoxNote inputs containing table cells with excessively large 'rowspan' or 'colspan' attribute values trigger algorithmic complexity conditions. This allows unauthenticated remote attackers to initiate resource exhaustion states, crashing or hanging the target document processing pipeline while bypassing configured timeouts.
A Local File Inclusion (LFI) and Arbitrary File Disclosure vulnerability exists in Docling and Docling Slim versions >= 2.16.0 up to 2.131.0. When parsing serialized DoclingDocument structures using the JSON input format, the backend fails to restrict image URI schemes, allowing remote attackers to retrieve local files and verify path existence on the host system during embedded document export.
Docling, a tool for parsing and processing diverse document formats, is vulnerable to arbitrary file read, arbitrary file write, and potential remote code execution (RCE) in versions 2.94.0 through 2.131.0. The vulnerability occurs when applications configure Docling to use the Tectonic engine for rendering TikZ diagrams into images. Because the compilation did not restrict hazardous TeX primitives or sandbox the environment, an attacker can supply crafted documents containing malicious TikZ definitions to access or modify local files and execute arbitrary commands under the privileges of the processing application.
An SSRF guard bypass vulnerability in the Docling document conversion engine allows unauthenticated attackers to bypass internal IP access controls. The vulnerability exists due to a DNS rebinding Time-of-Check Time-of-Use (TOCTOU) condition, URL authority parsing inconsistencies, and unvalidated network requests triggered during headless browser page rendering.
A technical analysis of CVE-2026-105742 (GHSA-p3fw-7699-7926), a sensitive information disclosure vulnerability in the Docling document processing library. Vulnerable versions of Docling indiscriminately forward custom HTTP headers, such as authentication tokens, to arbitrary third-party origins and during cross-origin redirects while fetching remote image assets from untrusted HTML and EPUB documents.