# Open WebUI has a Server-Side Request Forgery (SSRF) bypass in `validate_url`

Open WebUI's validate_url used urlparse while requests parsed the same URL differently, letting `http://127.0.0.1:6666\@baidu.com` bypass private-IP filtering and reach internal hosts.

- Payout: Research
- Severity: high
- Program: Open WebUI
- Found by: Fushuling, RacerZ-fighting
- Disclosed: 2026-05-14
- CVE: CVE-2026-45400
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-8w7q-q5jp-jvgx
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-8w7q-q5jp-jvgx
- Tags: area:web domain:web impact:internal-access kind:research platform:ghsa sev:high tech:python technique:parser-differential vuln:ssrf

**Target:** URL validation in web fetch / RAG file loader (files.py)
**Root cause:** validate_url extracts the hostname with urllib.parse.urlparse, which treats `\` as a normal character and `@` as the userinfo delimiter, yielding the public host after `@`. The requests library instead treats `\` as a path separator, so it connects to the host before it.
**Steps:**
1. Observe validate_url resolves parsed_url.hostname and rejects private IPs when ENABLE_RAG_LOCAL_WEB_FETCH is false.
2. Craft URL `http://127.0.0.1:6666\@baidu.com` (or `https://127.0.0.1:6666\@1.1.1.1/`).
3. urlparse returns hostname `baidu.com`/`1.1.1.1` (public) so validation passes.
4. requests.get on the same URL connects to `127.0.0.1:6666`, returning internal service response.
**How found:** Noticed validation and request dispatch use different URL parsers; hypothesized a parsing differential around backslash and `@` handling, then tested both libraries against the same URL.
**Exploitation:** Attacker submits the crafted URL to any feature that calls validate_url then requests.get (e.g. web fetch in files.py), causing the server to issue requests to internal/loopback services and return their responses.
**Insight:** When a validator and the HTTP client are different libraries, fuzz delimiter characters (`\`, `@`, `#`, tabs, unicode) that each parser classifies differently; backslash-as-path in requests vs urlparse is a reliable host-confusion primitive.

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

**SSRF bypass URL payload**

```
http://127.0.0.1:6666\@baidu.com
```

