存档提取期间的任意文件访问(“Zip 压缩文件路径遍历漏洞”)¶
ID: go/zipslip
Kind: path-problem
Security severity: 7.5
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-022
Query suites:
- go-code-scanning.qls
- go-security-extended.qls
- go-security-and-quality.qls
如果未正确验证存档中的文件名,则从恶意 zip 文件或类似类型的存档中提取文件时,可能会面临目录遍历攻击的风险。存档路径。
Zip 存档包含表示存档中每个文件的存档条目。这些条目包括条目的文件路径,但这些文件路径不受限制,并且可能包含意外的特殊元素,例如目录遍历元素 (..
)。如果使用这些文件路径创建文件系统路径,则文件操作可能会在意外的位置发生。这可能会导致敏感信息被泄露或删除,或者攻击者能够通过修改意外文件来影响行为。
例如,如果 zip 文件包含文件条目 ..\sneaky-file
,并且 zip 文件被提取到目录 c:\output
中,则简单地组合路径会导致输出文件路径为 c:\output\..\sneaky-file
,这将导致文件被写入 c:\sneaky-file
。
建议¶
确保验证从 zip 存档条目构造的输出路径,以防止将文件写入意外的位置。
写入 zip 存档条目中的输出文件的建议方法是检查路径中是否出现“..
”。
示例¶
在此示例中,提取存档时未验证文件路径。如果 archive.zip
包含相对路径(例如,如果它是通过类似 zip archive.zip ../file.txt
的命令创建的),则执行此代码可能会写入目标目录以外的位置。
package main
import (
"archive/zip"
"io/ioutil"
"path/filepath"
)
func unzip(f string) {
r, _ := zip.OpenReader(f)
for _, f := range r.File {
p, _ := filepath.Abs(f.Name)
// BAD: This could overwrite any file on the file system
ioutil.WriteFile(p, []byte("present"), 0666)
}
}
要修复此漏洞,我们需要检查路径中是否包含任何“..
”元素。
package main
import (
"archive/zip"
"io/ioutil"
"path/filepath"
"strings"
)
func unzipGood(f string) {
r, _ := zip.OpenReader(f)
for _, f := range r.File {
p, _ := filepath.Abs(f.Name)
// GOOD: Check that path does not contain ".." before using it
if !strings.Contains(f.Name, "..") {
ioutil.WriteFile(p, []byte("present"), 0666)
}
}
}
参考¶
Snyk:Zip 压缩文件路径遍历漏洞。
OWASP:路径遍历。
常见弱点枚举:CWE-22。