{
  "id": 17146449,
  "title": "A .nemo checkpoint is a tar file: two risks your model scanner may not open",
  "url": "https://urgent.news/2026/10/29/a-nemo-checkpoint-is-a-tar-file-two-risks-your-model-scanner-may-not",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-29T23:55:05.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/munimv2/a-nemo-checkpoint-is-a-tar-file-two-risks-your-model-scanner-may-not-open-c80"
  },
  "original_language": "en",
  "account": "A .nemo checkpoint is essentially a tar file: two potential risks your model scanner may overlook. NVIDIA NeMo stores models as .nemo files, which appear opaque but are in fact a tar archive that contains a model_config.yaml, model_weights.ckpt, and sometimes a tokenizer or vocabulary. When you call restore_from, NeMo untars the archive and torch.load-s the weights, meaning the loader treats the tar as transparent. A scanner that doesn't open the .nemo file misses out on two distinct risks.\n\nRisk 1 involves a pickle inside a torch.save file (model_weights.ckpt). This pickle can hold a __reduce__ gadget that executes on load, potentially running malicious code. Opcode-only pickle scanners and extension routers can handle .pkl or .pt files, but they fail to untar the .nemo first, so any gadget inside remains undiscovered. .nemo files are one of 22 pickle loading paths documented in The Art of Hide and Seek (USENIX Security 26, arXiv:2508.19774). Even my own toolkit's configuration detectors failed to unpack .nemo or .ckpt files.\n\nRisk 2 pertains to arbitrary file write on extraction (CVE-2024-0129). In NeMo versions prior to r2.0.0rc0, _unpack_nemo_file called tar.extractall() without sanitizing member names. If a member is named ../../something or contains an absolute path, it can be written outside the extraction folder, causing an arbitrary file write (CWE-22). This can lead to code execution. Older NeMo versions are at risk if you run an untrusted .nemo file, as it could overwrite files simply by being restored. To mitigate this, I added nemo_container_scan.py to the open-source keras-model-scan toolkit. This tool opens the tar in memory, walks members individually without extracting anything to disk, peels nested torch.save zips, and disassembles inner pickles using pickletools. It never imports torch or NeMo, avoids calling extractall, and never unpickles or runs anything. Sizes and member counts are capped, and the rule sets severities: NEMO001 for high risk (pickle import), NEMO010 for medium risk (pickle checkpoint without dangerous imports), NEMO020 for high risk (escaping extract root), and NEMO021 for medium risk (symlinks or hardlinks pointing outside the archive). Using nemo_container_scan.py, one can run 'python nemo_container_scan.py model.nemo', which exits with 1 on any high finding, allowing CI jobs to gate accordingly. The tool reads members via tar.next() instead of getmembers(), accommodating malformed trailing blocks in some .nemo files. Please note, this is static review, not exploitation. It flags imports, container layout, and escaping member names but does not prove exploitability or run proof of concepts. It peels one nested zip layer and reports rather than opening formats the standard library cannot read. The takeaway is clear: a .nemo is a tar, and NeMo's restore_from opens it, so your scanner should do the same. This post, along with the tool described, was developed using AI agents for Munim, Inc., and is open-source under Apache-2.0. If you find any errors, the repository is the place to report them.",
  "summary": "NVIDIA NeMo saves models as .nemo files. It is easy to treat one as an opaque blob, but a .nemo is just a tar archive (uncompressed, or gzip/bz2/xz in older releases) that bundles a model_config.yaml with model_weights.ckpt and sometimes a tokenizer or vocabulary. When you call restore_from , NeMo untars the archive and torch.load -s the weights. So the loader treats the tar as transparent, and a…",
  "key_points": [],
  "editors_take": "Treating .nemo files as opaque archives rather than transparent tarballs creates security blind spots that allow malicious pickles and path traversal exploits to bypass standard model scanners.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}