Mar 1, 2026·5 min read·75 visits
Gradio versions prior to 6.6.0 leak the server's Hugging Face access token via insecurely signed session cookies in the mocked OAuth flow. Attackers can decrypt the session to steal credentials or use an open redirect for phishing.
A critical vulnerability in the Gradio Python package allows unauthenticated remote attackers to extract sensitive Hugging Face access tokens from the server environment. The flaw exists in the 'mocked' OAuth implementation used when the application runs outside of Hugging Face Spaces. Additionally, an open redirect vulnerability facilitates phishing attacks. These issues are resolved in version 6.6.0.
CVE-2026-27167 describes a critical security failure in gradio, a popular Python library for building machine learning demonstrations. The vulnerability specifically affects the OAuth authentication flow when the application is hosted in environments other than Hugging Face Spaces (e.g., local development, on-premise servers, or third-party clouds).
When running in these environments, Gradio defaults to a 'mocked' OAuth flow to simulate authentication without requiring a full provider configuration. However, this implementation contained a severe logic error: it retrieved the actual Hugging Face authentication token from the server's environment (specifically HF_TOKEN) and embedded it into the user's session cookie. Combined with a weak, predictable signing key for the session cookie, this allows remote attackers to recover the plaintext credentials.
Furthermore, the login endpoint failed to validate the _target_url parameter, enabling an Open Redirect (CWE-601). This allows attackers to craft URLs that appear to be legitimate authentication links but redirect victims to malicious domains after the mock login completes.
The vulnerability stems from three converging failures in gradio/oauth.py:
1. Insecure Default Credential Usage (CWE-522)
The function _get_mocked_oauth_info was designed to provide dummy user data for the mocked login flow. Instead of returning static placeholder data, the implementation called huggingface_hub.get_token(). This function retrieves the active authentication token from the server's environment variables or local cache. Consequently, the server's identity credential was serialized into the access_token field of every user session.
2. Predictable Cryptographic Signing Key (CWE-321)
Gradio uses signed cookies to store session state. The signing key is derived from the application's secret. In the mocked flow, if the developer did not explicitly set an OAUTH_CLIENT_SECRET, the application defaulted to a derived key that often resolved to the string "-v4" (or app_secret + "-v4" where app_secret was empty or predictable). This low-entropy secret allows attackers to easily forge or decrypt session cookies offline.
3. Unvalidated Redirect Target (CWE-601)
The _redirect_to_target function accepted a _target_url query parameter and passed it directly to fastapi.responses.RedirectResponse. Lacking any validation or sanitization, the application would honor redirects to external schemas (e.g., https://evil.com), facilitating phishing attacks leveraged against the trusted domain of the Gradio app.
The patch introduced in version 6.6.0 addresses the vulnerability by replacing the dynamic token retrieval with a static string and enforcing strict URL parsing on redirects.
In the vulnerable version, the code actively fetched the environment token:
# Vulnerable: gradio/oauth.py
def _get_mocked_oauth_info() -> dict:
# DANGEROUS: Fetches the actual server token
token = huggingface_hub.get_token()
return {
"access_token": token,
"user": {"username": "user", "id": "1"}
}The patched version replaces this with a safe constant:
# Fixed: gradio/oauth.py
def _get_mocked_oauth_info() -> dict:
# SAFE: Returns a static placeholder string
return {
"access_token": "mock-oauth-token-for-local-dev",
"user": {"username": "user", "id": "1"}
}The redirection logic was updated to strip the domain and scheme, forcing all redirects to be relative to the application root:
# Fixed: gradio/oauth.py
import urllib.parse
def _redirect_to_target(request: Request, default_target: str = "/") -> RedirectResponse:
target = request.query_params.get("_target_url", default_target)
# PATCH: Parse the URL and reconstruct only the path and query
parsed = urllib.parse.urlparse(target)
safe_target = parsed.path or "/"
if parsed.query:
safe_target += "?" + parsed.query
return RedirectResponse(safe_target)An attacker can exploit this vulnerability without authentication if the Gradio server is accessible over the network. The attack chain proceeds as follows:
http://<target>/login/huggingface. The _target_url parameter is optional but can be used to test the Open Redirect simultaneously.307 Temporary Redirect (or similar) and sets a session cookie. This cookie contains the base64-encoded and signed session data."-v4", the attacker can use a tool like itsdangerous or a simple Python script to unsign the cookie without needing a brute-force attack.access_token field. In vulnerable versions, this field contains the server's live HF_TOKEN.HF_TOKEN to authenticate against the Hugging Face API, potentially accessing private repositories, modifying models, or poisoning datasets associated with the server owner's account.The impact of this vulnerability is Critical due to the high value of the compromised credentials.
HF_TOKEN may belong to a user with administrative privileges or write access to high-value models and datasets. Exposure allows unauthorized access to intellectual property and sensitive training data.Likelihood: The exploitation difficulty is Low (AC:L) because the signing key is predictable by default in the affected configuration. The vector is Network (AV:N) and requires no privileges (PR:N).
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
gradio Gradio | >= 4.16.0, < 6.6.0 | 6.6.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-522 (Insufficiently Protected Credentials) |
| CWE ID | CWE-601 (Open Redirect) |
| CVSS v3.1 | 9.1 (Critical) |
| Attack Vector | Network |
| Exploit Status | PoC Available |
| Patch Date | 2026-02-17 |
The application transmits credentials to an actor that is not authorized to see them, or stores credentials in a location that is accessible to unauthorized actors.
An authorization bypass and credential oracle vulnerability in pyload-ng allows authenticated users with minimal or no privileges to brute-force the administrator password. This is achieved through sensitive API methods exposed globally combined with a non-constant-time password hash comparison algorithm.
An authentication bypass vulnerability in pyLoad allows unauthenticated remote attackers to gain administrative API access. The vulnerability is caused by a logical flaw in the API key cache validation lookup, where authentication states are cached using only the public key identifier, skipping cryptographic token verification on cache hits.
An authorization bypass vulnerability in Strawberry GraphQL between versions 0.217.0 and 0.326.1 occurs when a synchronous permission handler returns an awaitable object (such as an unawaited coroutine). Due to Python's truthiness rules, the unawaited coroutine is evaluated as True, leading to an immediate bypass of security policies.
An uncontrolled resource consumption vulnerability in Strawberry GraphQL allows unauthenticated remote attackers to trigger a Denial of Service on persistent WebSocket connections using the legacy graphql-ws protocol. When the server enforces max_subscriptions_per_connection, naturally terminating subscriptions are not cleared from memory registries, leading to exhaustion of connection slots.
A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.
NearForm fast-jwt prior to version 6.3.0 is vulnerable to an input validation flaw where configuring verifier properties (such as clockTolerance, clockTimestamp, and cacheTTL) with non-finite values like Infinity or NaN allows attackers to bypass temporal claim validations, including expiration (exp) and activation (nbf) boundaries. This validation bypass can result in unauthorized session persistence and cache poisoning.