You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

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()

Status Severity CWE CVSS Target Platform

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:

  1. Run python3 poc_nemo.py β€” generates /tmp/malicious_model.nemo
  2. Create a HuggingFace repo (e.g. eric-gachara/nemo-zipslip-poc)
  3. Upload malicious_model.nemo to the repo
  4. Enable protectai-bot read access in repo settings
  5. Include HuggingFace URL in the huntr submission form
Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support