Instructions to use ericblackgachara/nemo-path-traversal-poc with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use ericblackgachara/nemo-path-traversal-poc with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
NeMo β CWE-22 Path Traversal (Zip Slip) via load_config()
Summary
| Field | Value |
|---|---|
| Target | NVIDIA/NeMo |
| Version | 2.8.0rc0 (latest as of 2026-06-01) |
| Platform | huntr.com/bounties/disclose/models?target=Nemo |
| Severity | High |
| CWE | CWE-22 β Path Traversal (Zip Slip) |
| CVSS 3.1 | 7.4 β AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:N |
| Est. Payout | $3,000β$4,000 |
| Confirmed | YES β Python 3.13.12 |
Root Cause (one line)
load_config() in nemo/utils/model_utils.py passes an attacker-controlled archive member path prefix directly to tar.extract() without calling _safe_extract(), enabling arbitrary file write via a crafted .nemo archive.
Trigger Path
malicious.nemo (TAR archive)
βββ ../../home/user/model_config.yaml β path-traversing member name
β User calls:
load_config("malicious.nemo")
β NeMo calls:
detect_prefix(tar.getnames()) β prefix = "../../home/user/"
tar.extract("../../home/user/model_config.yaml", path=tmp) β VULNERABLE
β Result:
/home/user/model_config.yaml β written OUTSIDE tmp with attacker-controlled content
Vulnerable Lines
nemo/utils/model_utils.py:85 tar.extract(f"{prefix}{MODEL_CONFIG}", path=tmp)
nemo/utils/model_utils.py:748 maybe_tar.extract(f"{prefix}{arti_file}", path=output_dir)
Reproduction
# Python 3.10, 3.11, 3.12, or 3.13
python3 poc_nemo.py
# Expected output: "[+] ZIP SLIP CONFIRMED"
Expected Output
[+] Archive member (traversal path): ../../tmp/nemo_poc_pwned/model_config.yaml
[*] detect_prefix() returned: '../../tmp/nemo_poc_pwned/'
[*] Files inside safe tmp: NONE (traversal escaped)
[+] ZIP SLIP CONFIRMED
[+] File written outside tmp: /tmp/nemo_poc_pwned/model_config.yaml
Suggested Fix
Replace tar.extract() with SaveRestoreConnector._safe_extract() in both locations, or add Python 3.12+ filter='data' parameter to block traversal. The safe wrapper already exists in save_restore_connector.py and is used by restore_from() β load_config() and save_artifacts() simply need to use it too.
Files
| File | Purpose |
|---|---|
poc_nemo.py |
Working PoC β creates malicious .nemo and triggers the path traversal |
report.md |
huntr submission β plain prose, paste directly into form fields |
poc-evidence.html |
HTML evidence page with styled terminal output |
README.md |
This file |
HuggingFace Upload (required by huntr)
huntr's model program requires the malicious .nemo to be hosted on a public HuggingFace repo with protectai-bot access. Steps:
- Run
python3 poc_nemo.pyβ generates/tmp/malicious_model.nemo - Create a HuggingFace repo (e.g.
eric-gachara/nemo-zipslip-poc) - Upload
malicious_model.nemoto the repo - Enable protectai-bot read access in repo settings
- Include HuggingFace URL in the huntr submission form
- Downloads last month
- -