Zip Slip漏洞综述
字数 1373 2025-08-29 08:32:18

Zip Slip漏洞深度分析与防御指南

1. Zip Slip漏洞概述

Zip Slip是一种广泛存在的关键存档提取漏洞,允许攻击者在系统中任意写入文件,可能导致远程命令执行。该漏洞由Snyk安全团队于2018年6月5日公开披露,影响上千个工程项目,包括HP、亚马逊、Apache等知名企业的项目。

1.1 漏洞影响范围

  • 影响生态系统:Java、JavaScript、Ruby、.NET和Go等
  • 影响存档格式:zip、tar、jar、war、cpio、apk、rar、7z等
  • 特别严重领域:Java生态系统由于缺乏高效处理存档文件的中心库函数,问题尤为突出

2. 漏洞原理与利用方式

2.1 漏洞本质

Zip Slip是一种目录遍历漏洞,攻击者通过构造含有特殊路径的存档文件(如../../evil.sh),在提取时突破目标目录限制,向系统任意位置写入文件。

2.2 利用条件

  1. 恶意存档文件:包含一个或多个带有目录遍历路径的文件
  2. 不安全的提取代码:提取过程未对文件路径进行验证

2.3 典型攻击流程

  1. 攻击者构造包含恶意路径的存档文件(如../../../tmp/evil.sh
  2. 受害者应用提取该存档文件
  3. 恶意文件被写入系统敏感位置(如/tmp/etc等)
  4. 当系统或用户执行被覆盖的文件时,触发远程命令执行

3. 漏洞代码示例与修复方案

3.1 Java生态系统

漏洞代码示例

Enumeration<ZipEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
    ZipEntry e = entries.nextElement();
    File f = new File(destinationDir, e.getName());
    InputStream input = zip.getInputStream(e);
    IOUtils.copy(input, write(f));
}

修复方案

Enumeration<ZipEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
    ZipEntry e = entries.nextElement();
    File f = new File(destinationDir, e.getName());
    String canonicalPath = f.getCanonicalPath();
    if (!canonicalPath.startsWith(destinationDir.getCanonicalPath() + File.separator)) {
        throw new IOException("Entry is outside of the target dir: " + e.getName());
    }
    InputStream input = zip.getInputStream(e);
    IOUtils.copy(input, write(f));
}

3.2 JavaScript生态系统

漏洞代码示例

fs.createReadStream(path.join(dest, entry.path))
  .pipe(fs.createWriteStream(path.join(targetPath, entry.path)));

修复方案

const extractPath = path.join(targetPath, entry.path);
if (extractPath.indexOf(path.resolve(targetPath)) !== 0) {
    throw new Error("Entry is outside of the target dir: " + entry.path);
}
fs.createReadStream(path.join(dest, entry.path))
  .pipe(fs.createWriteStream(extractPath));

3.3 .NET生态系统

漏洞代码示例

var entry = zip.GetEntry("../../evil.sh");
var fullPath = Path.Combine(destinationDirectory, entry.FullName);
entry.ExtractToFile(fullPath);

修复方案

var entry = zip.GetEntry("../../evil.sh");
var fullPath = Path.GetFullPath(Path.Combine(destinationDirectory, entry.FullName));
if (!fullPath.StartsWith(Path.GetFullPath(destinationDirectory))) {
    throw new IOException("Entry is outside of the target dir: " + entry.FullName);
}
entry.ExtractToFile(fullPath);

3.4 Go生态系统

漏洞代码示例

for _, file := range reader.File {
    err := os.MkdirAll(filepath.Dir(file.Name), os.ModePerm)
    if err != nil {
        return err
    }
    outFile, err := os.Create(file.Name)
    if err != nil {
        return err
    }
    // ...
}

修复方案

for _, file := range reader.File {
    destPath := filepath.Join(dest, file.Name)
    if !strings.HasPrefix(destPath, filepath.Clean(dest)+string(os.PathSeparator)) {
        return fmt.Errorf("%s: illegal file path", file.Name)
    }
    err := os.MkdirAll(filepath.Dir(destPath), os.ModePerm)
    if err != nil {
        return err
    }
    outFile, err := os.Create(destPath)
    if err != nil {
        return err
    }
    // ...
}

4. 漏洞检测与防御措施

4.1 检测方法

  1. 代码审计:检查项目中是否存在不安全的存档提取代码
  2. 依赖扫描:使用工具(如Snyk)扫描项目依赖中是否存在有漏洞的库
  3. 测试用例:构造恶意存档文件测试应用是否会被利用

4.2 防御措施

  1. 路径规范化与验证

    • 使用getCanonicalPath()(Java)、Path.GetFullPath()(.NET)、filepath.Clean()(Go)等方法规范化路径
    • 验证最终路径是否在目标目录内
  2. 使用安全库

    • 优先使用已修复该漏洞的库版本
    • 避免从StackOverflow等社区复制未经安全验证的代码
  3. 安全开发实践

    • 在CI/CD流程中加入安全测试
    • 定期更新依赖库
    • 实施最小权限原则,限制应用的文件系统访问权限

5. 受影响项目与资源

5.1 已知受影响项目

  • Oracle
  • Amazon
  • Spring/Pivotal
  • LinkedIn
  • Twitter
  • Alibaba
  • Jenkins
  • Eclipse
  • OWASP
  • SonarQube
  • OpenTable
  • Arduino
  • ElasticSearch
  • Selenium
  • Gradle
  • JetBrains

5.2 参考资源

  1. Snyk官方漏洞库
  2. 技术白皮书

6. 总结

Zip Slip是一个严重且广泛存在的漏洞,主要由于不安全的存档提取实现导致。防御该漏洞的关键在于:

  1. 对所有提取的文件路径进行规范化处理
  2. 严格验证最终路径是否在目标目录内
  3. 使用已修复该漏洞的库版本
  4. 在开发流程中加入安全测试环节

通过实施这些措施,可以有效防范Zip Slip漏洞带来的安全风险。

Zip Slip漏洞深度分析与防御指南 1. Zip Slip漏洞概述 Zip Slip是一种广泛存在的关键存档提取漏洞,允许攻击者在系统中任意写入文件,可能导致远程命令执行。该漏洞由Snyk安全团队于2018年6月5日公开披露,影响上千个工程项目,包括HP、亚马逊、Apache等知名企业的项目。 1.1 漏洞影响范围 影响生态系统 :Java、JavaScript、Ruby、.NET和Go等 影响存档格式 :zip、tar、jar、war、cpio、apk、rar、7z等 特别严重领域 :Java生态系统由于缺乏高效处理存档文件的中心库函数,问题尤为突出 2. 漏洞原理与利用方式 2.1 漏洞本质 Zip Slip是一种目录遍历漏洞,攻击者通过构造含有特殊路径的存档文件(如 ../../evil.sh ),在提取时突破目标目录限制,向系统任意位置写入文件。 2.2 利用条件 恶意存档文件 :包含一个或多个带有目录遍历路径的文件 不安全的提取代码 :提取过程未对文件路径进行验证 2.3 典型攻击流程 攻击者构造包含恶意路径的存档文件(如 ../../../tmp/evil.sh ) 受害者应用提取该存档文件 恶意文件被写入系统敏感位置(如 /tmp 、 /etc 等) 当系统或用户执行被覆盖的文件时,触发远程命令执行 3. 漏洞代码示例与修复方案 3.1 Java生态系统 漏洞代码示例 修复方案 3.2 JavaScript生态系统 漏洞代码示例 修复方案 3.3 .NET生态系统 漏洞代码示例 修复方案 3.4 Go生态系统 漏洞代码示例 修复方案 4. 漏洞检测与防御措施 4.1 检测方法 代码审计 :检查项目中是否存在不安全的存档提取代码 依赖扫描 :使用工具(如Snyk)扫描项目依赖中是否存在有漏洞的库 测试用例 :构造恶意存档文件测试应用是否会被利用 4.2 防御措施 路径规范化与验证 : 使用 getCanonicalPath() (Java)、 Path.GetFullPath() (.NET)、 filepath.Clean() (Go)等方法规范化路径 验证最终路径是否在目标目录内 使用安全库 : 优先使用已修复该漏洞的库版本 避免从StackOverflow等社区复制未经安全验证的代码 安全开发实践 : 在CI/CD流程中加入安全测试 定期更新依赖库 实施最小权限原则,限制应用的文件系统访问权限 5. 受影响项目与资源 5.1 已知受影响项目 Oracle Amazon Spring/Pivotal LinkedIn Twitter Alibaba Jenkins Eclipse OWASP SonarQube OpenTable Arduino ElasticSearch Selenium Gradle JetBrains 5.2 参考资源 Snyk官方漏洞库 技术白皮书 6. 总结 Zip Slip是一个严重且广泛存在的漏洞,主要由于不安全的存档提取实现导致。防御该漏洞的关键在于: 对所有提取的文件路径进行规范化处理 严格验证最终路径是否在目标目录内 使用已修复该漏洞的库版本 在开发流程中加入安全测试环节 通过实施这些措施,可以有效防范Zip Slip漏洞带来的安全风险。