CVE-2025-5320
Executive Summary
CVE-2025-5320 is a problematic vulnerability in the Gradio web application framework (gradio-app/gradio) affecting versions up to and including 5.29.1. The flaw resides in the is_valid_origin function within the CORS (Cross-Origin Resource Sharing) handler. By manipulating the localhost_aliases argument, an attacker can bypass origin validation, leading to unauthorized cross-origin requests. This is classified as a URL Redirection to Untrusted Site ('Open Redirect') vulnerability (CWE-601). The attack complexity is high, requiring specific conditions, but a proof-of-concept has been publicly disclosed. The vendor was contacted but did not respond, leaving the vulnerability unpatched.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Gradio is a Python package widely used in the machine learning and data science community for creating interactive web demos. This vulnerability affects the supply chain by potentially allowing malicious actors to craft Gradio applications that perform open redirects or bypass CORS protections. Organizations using Gradio in production or internal tools should treat this as a high-priority supply chain risk, as the package is often installed via PyPI (pip install gradio). The lack of a vendor patch means users must rely on manual mitigations or version pinning.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N
- Base Score: 4.2 (Medium)
- Attack Vector (AV): Network (N) – Exploitable remotely.
- Attack Complexity (AC): High (H) – Requires specific conditions (e.g., knowledge of localhost aliases).
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): Required (R) – Victim must interact with a malicious link or page.
- Scope (S): Unchanged (U) – The vulnerable component and the impacted component are the same.
- Confidentiality (C): Low (L) – Limited information disclosure possible.
- Integrity (I): Low (L) – Limited ability to modify data.
- Availability (A): None (N) – No impact on availability.
Threat Level: Medium. While the CVSS score is moderate, the public availability of exploit details and the lack of a patch elevate the risk for organizations using Gradio in exposed environments.
Deep Dive & Mechanics
The vulnerability is located in the is_valid_origin function of Gradio's CORS handler. This function is responsible for validating the Origin header of incoming HTTP requests to prevent cross-origin attacks. The function uses a list of localhost_aliases (e.g., localhost, 127.0.0.1, [::1]) to determine if a request originates from a trusted local source.
Root Cause: The is_valid_origin function does not properly sanitize or validate the localhost_aliases argument. An attacker can manipulate this argument to include arbitrary hostnames or IP addresses, effectively bypassing the origin check. For example, by providing a crafted localhost_aliases value that includes a malicious domain, the function may incorrectly treat that domain as a trusted local origin.
Attack Scenario:
- An attacker hosts a malicious Gradio application or crafts a web page that interacts with a legitimate Gradio instance.
- The attacker sends a request with a manipulated
Originheader that includes a specially craftedlocalhost_aliasesvalue. - The vulnerable
is_valid_originfunction incorrectly validates the origin, allowing the cross-origin request to proceed. - This can lead to open redirects, CSRF-like attacks, or information leakage.
Technical Details:
- The function likely uses a simple string comparison or regex to check if the origin matches any of the localhost aliases.
- The manipulation involves injecting additional entries into the
localhost_aliaseslist or exploiting how the function parses the argument. - The attack is remote but requires high complexity due to the need to craft specific alias values.
Vulnerable vs. Patched Code
Since no official patch is available, the following is a hypothetical comparison based on the vulnerability description.
Vulnerable Code (Conceptual):
def is_valid_origin(origin, localhost_aliases):
# Vulnerable: Directly uses localhost_aliases without sanitization
for alias in localhost_aliases:
if origin == alias or origin.startswith(alias):
return True
return False
Patched Code (Hypothetical):
def is_valid_origin(origin, localhost_aliases):
# Patched: Validate and sanitize localhost_aliases
allowed_aliases = ['localhost', '127.0.0.1', '[::1]', '0.0.0.0']
for alias in localhost_aliases:
if alias not in allowed_aliases:
continue
if origin == alias or origin.startswith(alias):
return True
return False
Key Difference: The patched version restricts localhost_aliases to a predefined set of safe values, preventing injection of arbitrary domains.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target Gradio application running version <= 5.29.1.
- Ability to send HTTP requests to the target (e.g., via browser or script).
- Knowledge of the target's
localhost_aliasesconfiguration (default or custom).
Exploitation Steps:
- Identify a Gradio endpoint that uses CORS validation (e.g.,
/api/predict). - Craft a malicious web page that sends a cross-origin request to the target.
- Manipulate the
Originheader to include a craftedlocalhost_aliasesvalue. For example:- Set
Origin: http://evil.comand includeevil.comin thelocalhost_aliasesargument (if controllable via query parameter or POST data).
- Set
- If successful, the target will accept the cross-origin request, potentially allowing data exfiltration or open redirect.
Proof-of-Concept (Python):
import requests
target_url = "http://victim-gradio-app.com/api/predict"
# Crafted localhost_aliases to include malicious domain
malicious_aliases = ["localhost", "127.0.0.1", "evil.com"]
headers = {
"Origin": "http://evil.com",
"X-Localhost-Aliases": ",".join(malicious_aliases) # Hypothetical injection point
}
response = requests.get(target_url, headers=headers)
print(response.status_code, response.text)
Note: The exact injection point may vary. This is a conceptual example.
Blue Team (Detection & Defense)
Detection:
- Monitor for unusual
Originheaders that do not match expected patterns. - Log and alert on requests with manipulated
localhost_aliasesparameters. - Use the detection rules provided in the Detection Engineering section.
Defense:
- Immediate: Restrict access to Gradio applications using network-level controls (e.g., firewall rules, VPN).
- Configuration: Override the
localhost_aliasesin Gradio's configuration to a strict whitelist. - WAF: Deploy a Web Application Firewall (WAF) rule to block requests with suspicious
Originheaders orlocalhost_aliasesparameters. - Monitoring: Enable detailed logging for CORS-related events.
Indicators of Compromise (IOCs)
- Network:
- HTTP requests with
Originheaders containing unexpected domains (e.g.,evil.com,malicious.net). - Requests with custom headers like
X-Localhost-AliasesorX-Forwarded-Hostcontaining unusual values.
- HTTP requests with
- Logs:
- Gradio access logs showing
is_valid_originfailures or successes for non-standard origins. - Repeated attempts to access Gradio endpoints from external IPs with manipulated headers.
- Gradio access logs showing
- File System:
- Modified Gradio configuration files (e.g.,
config.py) containing alteredlocalhost_aliases.
- Modified Gradio configuration files (e.g.,
- Behavioral:
- Unexpected open redirects from Gradio application URLs.
- Cross-origin requests from unknown domains to Gradio API endpoints.
Detection Engineering
YARA Rule
rule CVE_2025_5320_Gradio_CORS_Bypass {
meta:
description = "Detects attempts to exploit CVE-2025-5320 in Gradio CORS handler"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-5320"
strings:
$s1 = "is_valid_origin" ascii wide nocase
$s2 = "localhost_aliases" ascii wide nocase
$s3 = "Origin" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2025-5320 Gradio CORS Bypass Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects HTTP requests attempting to exploit CVE-2025-5320 by manipulating localhost_aliases
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: gradio
detection:
selection:
cs-method: 'GET' or 'POST'
cs-uri-query|contains: 'localhost_aliases'
cs-headers|contains: 'Origin'
condition: selection
falsepositives:
- Legitimate use of custom localhost aliases in development environments
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-5320 Gradio CORS Bypass Attempt"; flow:to_server; content:"localhost_aliases"; http_client_body; content:"Origin"; http_header; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: If a patched version becomes available, upgrade immediately. Monitor the Gradio GitHub repository for updates.
- Network Segmentation: Place Gradio applications behind a reverse proxy or firewall that validates origins.
- Configuration Hardening: Manually override the
localhost_aliasesin Gradio's source code or configuration to a strict whitelist (e.g.,['localhost', '127.0.0.1']). - Disable CORS: If not required, disable CORS entirely in Gradio configuration.
Long-Term Measures:
- Implement a Web Application Firewall (WAF) with custom rules to block suspicious origin headers.
- Conduct a security audit of all Gradio applications in the environment.
- Subscribe to Gradio security advisories for future patches.
Workaround (Code-Level):
If you have access to the Gradio source code, modify the is_valid_origin function to sanitize localhost_aliases:
def is_valid_origin(origin, localhost_aliases):
allowed_aliases = ['localhost', '127.0.0.1', '[::1]', '0.0.0.0']
for alias in localhost_aliases:
if alias not in allowed_aliases:
continue
if origin == alias or origin.startswith(alias):
return True
return False
Valters IT
Securing Digital Frontiers