Open redirect via `/file=<URL>` on pinned gradio 4.x (CVE-2024-8021)
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:
# 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://<omniparse-host>/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=<URL> 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.
- 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):
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)- Issue the open-redirect request:
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.
- Curl equivalent for manual verification:
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: 0Expected 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 installresolves to4.44.1today; 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
Locationheader 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_proofSSRF helper. All 3 CVEs are patched in gradio 4.31.4+ (my empirical Run on 4.44.1 returnedHTTP 500for the literal CVE-2024-4941 PoC, confirming thecheck_all_files_in_cachefix is active). Thecat_proofclaim 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).
Source: adithya-s-k/omniparse