CodeQL 文档

tar 文件解压缩期间的任意文件写入

ID: py/tarslip
Kind: path-problem
Security severity: 7.5
Severity: error
Precision: medium
Tags:
   - security
   - external/cwe/cwe-022
Query suites:
   - python-security-extended.qls
   - python-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

从恶意 tar 存档解压缩文件而不验证目标文件路径是否在目标目录内,可能会导致目标目录外部的文件被覆盖,因为存档路径中可能存在目录遍历元素(..)。

tar 存档包含表示存档中每个文件的存档条目。这些条目包括条目的文件路径,但这些文件路径不受限制,可能包含意外的特殊元素,例如目录遍历元素(..)。如果这些文件路径用于确定要写入存档项内容的输出文件,则该文件可能会写入意外的位置。这可能导致敏感信息被泄露或删除,或者攻击者能够通过修改意外文件来影响行为。

例如,如果 tar 存档包含文件条目..\sneaky-file,并且 tar 存档被解压缩到目录c:\output,则简单地组合路径会导致输出文件路径为c:\output\..\sneaky-file,这将导致文件被写入c:\sneaky-file

建议

确保从 tar 存档条目构建的输出路径经过验证,以防止将文件写入意外位置。

从 tar 存档条目写入输出文件的推荐方法是检查".."是否出现在路径中。

示例

在本示例中,存档在没有验证文件路径的情况下被解压缩。如果archive.tar包含相对路径(例如,如果它是由类似于tar -cf archive.tar ../file.txt的内容创建的),则执行此代码可能会写入目标目录外部的位置。

import sys
import tarfile

with tarfile.open(sys.argv[1]) as tar:
    #BAD : This could write any file on the filesystem.
    for entry in tar:
        tar.extract(entry, "/tmp/unpack/")

要修复此漏洞,我们需要检查路径中是否包含任何".."元素。

import sys
import tarfile
import os.path

with tarfile.open(sys.argv[1]) as tar:
    for entry in tar:
        #GOOD: Check that entry is safe
        if os.path.isabs(entry.name) or ".." in entry.name:
            raise ValueError("Illegal tar archive entry")
        tar.extract(entry, "/tmp/unpack/")

参考资料

  • ©2025GitHub, Inc.
  • 条款
  • 隐私