-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathZipSlip.qhelp
More file actions
68 lines (54 loc) · 2.82 KB
/
ZipSlip.qhelp
File metadata and controls
68 lines (54 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Extracting files from a malicious zip file, or similar type of archive,
is at risk of directory traversal attacks if filenames from the archive are
not properly validated.</p>
<p>Zip archives contain archive entries representing each file in the archive. These entries
include a file path for the entry, but these file paths are not restricted and may contain
unexpected special elements such as the directory traversal element (<code>..</code>). If these
file paths are used to create a filesystem path, then a file operation may happen in an
unexpected location. This can result in sensitive information being
revealed or deleted, or an attacker being able to influence behavior by modifying unexpected
files.</p>
<p>For example, if a zip file contains a file entry <code>..\sneaky-file</code>, and the zip file
is extracted to the directory <code>c:\output</code>, then naively combining the paths would result
in an output file path of <code>c:\output\..\sneaky-file</code>, which would cause the file to be
written to <code>c:\sneaky-file</code>.</p>
</overview>
<recommendation>
<p>Ensure that output paths constructed from zip archive entries are validated to prevent writing
files to unexpected locations.</p>
<p>The recommended way of writing an output file from a zip archive entry is to
verify that the normalized full path of the output file starts with a prefix that matches the
destination directory. Path normalization can be done with either
<code>java.io.File.getCanonicalFile()</code> or <code>java.nio.file.Path.normalize()</code>.
Prefix checking can be done with <code>String.startsWith(..)</code>, but it is better to use
<code>java.nio.file.Path.startsWith(..)</code>, as the latter works on complete path segments.
</p>
<p>Another alternative is to validate archive entries against a whitelist of expected files.</p>
</recommendation>
<example>
<p>In this example, a file path taken from a zip archive item entry is combined with a
destination directory. The result is used as the destination file path without verifying that
the result is within the destination directory. If provided with a zip file containing an archive
path like <code>..\sneaky-file</code>, then this file would be written outside the destination
directory.</p>
<sample src="examples/ZipSlipBad.java" />
<p>To fix this vulnerability, we need to verify that the normalized <code>file</code> still has
<code>destinationDir</code> as its prefix, and throw an exception if this is not the case.</p>
<sample src="examples/ZipSlipGood.java" />
</example>
<references>
<li>
Snyk:
<a href="https://snyk.io/research/zip-slip-vulnerability">Zip Slip Vulnerability</a>.
</li>
<li>
OWASP:
<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.
</li>
</references>
</qhelp>