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 ").
Vulnerable code ( permalink ):
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 ):
This inconsistency shows that NumpyReader was overlooked during security hardening.
The user cannot override this behavior:
The hardcoded allow_pickle=True on line 1276 overrides any user attempt to set it via kwargs.
User creates a data pipeline with LoadImage transform or uses any MONAI dataset class
A .npy or .npz file is provided as input (e.g., as part of a shared medical dataset)
LoadImage selects NumpyReader based on file extension
NumpyReader.read() calls np.load(name, allow_pickle=True)
Malicious pickle payload in the .npy file executes arbitrary code
An attacker can achieve arbitrary code execution on any machine running MONAI by:
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.
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.
Supply chain attack : Contributing a malicious .npy file to a MONAI tutorial, example, or bundle that other users download and run.
Supply chain attack : Contributing a malicious .npy file to a MONAI tutorial, example, or bundle that other users download and run.
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.
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).
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
