MONAI 路径遍历漏洞CVE-2026-21851
MONAI(Medical Open Network for AI)是由 NVIDIA 与顶级学术医疗中心联合发起的医疗影像深度学习开源框架,其基于 PyTorch 构建。
一、基本情况
MONAI核心价值是标准化医疗 AI 全生命周期开发、解决医学影像数据(3D/4D、DICOM、标注稀缺)挑战,打通科研到临床的落地路径。

提供从数据标注、模型训练到临床部署完整工具链,兼顾研究灵活性与临床合规性,支持 NVIDIA GPU 加速与AMD ROCm异构计算环境。
栋科技漏洞库关注到 MONAI 的_download_from_ngc_private()函数路径遍历(Zip Slip)漏洞,追踪CVE-2026-21851,CVSS 3.X分 5.3。
二、漏洞分析
CVE-2026-21851漏洞是包含1.5.1版本在内的早期版本中MONAI的_download_from_ngc_private()函数中存在路径遍历(Zip滑动)漏洞。
该函数在未进行路径验证的情况下使用了zipfile.ZipFile.extractall()。
在同一代码库中,其他类似的下载函数则正确地使用了现有的safe_extract_member()函数。
这似乎是一个实现上的疏忽,因为安全提取功能已在MONAI的其他地方实现并使用。
1、易受攻击的代码位置
文件:monai/bundle/scripts.py
第291-292行
函数:_download_from_ngc_private()
# monai/bundle/scripts.py - Lines 284-293
zip_path = download_path / f"{filename}_v{version}.zip"
with open(zip_path, "wb") as f:
f.write(response.content)
logger.info(f"Downloading: {zip_path}.")
if remove_prefix:
filename = _remove_ngc_prefix(filename, prefix=remove_prefix)
extract_path = download_path / f"{filename}"
with zipfile.ZipFile(zip_path, "r") as z:
z.extractall(extract_path) # <-- No path validation
logger.info(f"Writing into directory: {extract_path}.")
2、根本原因
代码直接调用z.extractall(extract_path),而未验证存档成员路径是否位于解压目录内。
3、安全代码已存在
MONAI已在monai/apps/utils.py(第125-154行)中提供了一个安全提取函数,该函数能够正确验证路径:
def safe_extract_member(member, extract_to):
"""Securely verify compressed package member paths to prevent path traversal attacks"""
# ... path validation logic ...
if os.path.isabs(member_path) or ".." in member_path.split(os.sep):
raise ValueError(f"Unsafe path detected in archive: {member_path}")
# Ensure path stays within extraction root
if os.path.commonpath([extract_root, target_real]) != extract_root:
raise ValueError(f"Unsafe path: path traversal {member_path}")
三、POC概念验证
1、创建一个恶意Zip文件
管理员已设置登录后刷新可查看输出:
Created: malicious_bundle.zip
Contents:
- monai_test_bundle/configs/metadata.json
- ../../../tmp/escaped_file.txt
2、展示差异
此脚本展示了易受攻击的模式(在_download_from_ngc_private中使用)与安全模式(在MONAI的其他地方使用)之间的差异:
管理员已设置登录后刷新可查看输出:
==================================================
VULNERABLE PATTERN (scripts.py:291-292)
==================================================
[VULNERABLE] Extraction completed without validation
Extracted: monai_test_bundle/configs/metadata.json
Extracted: tmp/escaped_file.txt
==================================================
SAFE PATTERN (apps/utils.py)
==================================================
[SAFE] Allowed: monai_test_bundle/configs/metadata.json
[SAFE] BLOCKED: ../../../tmp/escaped_file.txt
3、影响
利用利用所需条件
·攻击者必须控制或破坏一个NGC私有仓库
·受害者必须配置MONAI以从该存储库下载
·受害者必须使用source="ngc_private"参数
4、潜在影响
如果被利用,攻击者可能会在预期的解压目录之外写入文件。实际影响取决于:
运行MONAI的用户的权限
已泄露文件的目标位置
Python版本(较新版本内置了一些路径规范化功能)
5、缓解因素
要求攻击者控制一个NGC私有仓库
现代Python版本(3.12及以上)内置了一些路径规范化功能
与其他源相比,ngc_private源的使用频率较低
6、推荐修复方案
将直接的extractall()调用替换为MONAI现有的安全提取方法:
# monai/bundle/scripts.py
+ from monai.apps.utils import _extract_zip
def _download_from_ngc_private(...):
# ... existing code ...
extract_path = download_path / f"{filename}"
- 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}.")
这使_download_from_ngc_private()函数与其他下载函数保持一致,并确保所有下载源的安全性一致。
四、影响范围
MONAI <= 1.5.1
五、修复建议
MONAI > 1.5.1
六、参考链接
管理员已设置登录后刷新可查看