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
从恶意 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/")
参考资料¶
Snyk:Zip Slip 漏洞.
OWASP:路径遍历.
Python 库参考:TarFile.extract.
Python 库参考:TarFile.extractall.
通用弱点枚举:CWE-22.