|
3 | 3 | "qhelp.dtd"> |
4 | 4 | <qhelp> |
5 | 5 | <overview> |
6 | | -<p>Accessing paths controlled by users can allow an attacker to access unexpected resources. This |
7 | | -can result in sensitive information being revealed or deleted, or an attacker being able to influence |
8 | | -behavior by modifying unexpected files.</p> |
| 6 | +<p> User inputted file paths can often pose security risks if a program does not correctly handle them. In particular, if a user |
| 7 | +is meant to access files under a certain directory but does not enters a path under that directory, they can gain access to |
| 8 | +(and potentially modify/delete) unexpected, possibly sensitive resources. </p> |
9 | 9 |
|
10 | | -<p>Paths that are naively constructed from data controlled by a user may contain unexpected special characters, |
11 | | -such as "..". Such a path may potentially point to any directory on the file system.</p> |
| 10 | +<p> Suppose a program is to only accept paths that point to files/folders within directory <code>DIR</code>. |
| 11 | +To ensure that a user inputted path, say <code>SUBDIR</code>, is a subdirectory of <code>DIR</code>, the |
| 12 | +program verifies that <code>DIR</code> is a prefix of <code>SUBDIR</code>. |
| 13 | +However, this check is not satisfactory: unless <code>DIR</code> is not slash-terminated, |
| 14 | +<code>SUBDIR</code> may be allowed to also access siblings of <code>DIR</code> and not |
| 15 | +just children of <code>DIR</code>, which is a security issue. </p> |
12 | 16 |
|
13 | 17 | </overview> |
14 | 18 | <recommendation> |
15 | 19 |
|
16 | | -<p>Validate user input before using it to construct a file path. Ideally, follow these rules:</p> |
17 | | - |
18 | | -<ul> |
19 | | -<li>Do not allow more than a single "." character.</li> |
20 | | -<li>Do not allow directory separators such as "/" or "\" (depending on the file system).</li> |
21 | | -<li>Do not rely on simply replacing problematic sequences such as "../". For example, after applying this filter to |
22 | | -".../...//" the resulting string would still be "../".</li> |
23 | | -<li>Ideally use a whitelist of known good patterns.</li> |
24 | | -</ul> |
| 20 | +<p>If the user should only access items within a certain directory <code>DIR</code>, first ensure that <code>DIR</code> is slash-terminated, |
| 21 | +and then proceed (as normal) to verify that <code>DIR</code> is a prefix of the user-provided path, <code>SUBDIR</code>. Note, Java's <code>getCanonicalPath()</code> |
| 22 | +returns a <b>non</b>-slash-terminated path string, so a <code>"/"</code> must be added to <code>DIR</code> if that method is used. </p> |
25 | 23 |
|
26 | 24 | </recommendation> |
27 | 25 | <example> |
28 | 26 |
|
29 | | -<p>In this example, a file name is read from a <code>java.net.Socket</code> and then used to access a file in the |
30 | | -user's home directory and send it back over the socket. However, a malicious user could enter a file name which contains special |
31 | | -characters. For example, the string "../../etc/passwd" will result in the code reading the file located at |
32 | | -"/home/[user]/../../etc/passwd", which is the system's password file. This file would then be sent back to the user, |
33 | | -giving them access to all the system's passwords.</p> |
| 27 | +<p> |
| 28 | + |
| 29 | + |
| 30 | +In this example, the <code>if</code> statement checks if <code>parent.getCanonicalPath()</code> |
| 31 | +is a prefix of <code>dir.getCanonicalPath()</dir>. However, <code>parent.getCanonicalPath()</code> is |
| 32 | +not slash-terminated. So, the user that supplies <code>dir</code> may be allowed to access siblings of <code>parent</code> |
| 33 | +and not just children of <code>parent</code>, which is a security issue. |
| 34 | + |
| 35 | +</p> |
| 36 | + |
| 37 | +<sample src="PartialPathTraversalBad.java" /> |
| 38 | + |
| 39 | +<p> |
| 40 | + |
| 41 | +In this example, the <code>if</code> statement checks if <code>parent.getCanonicalPath() + File.separator </code> |
| 42 | +is a prefix of <code>dir.getCanonicalPath()</code>. Because <code>parent.getCanonicalPath() + File.separator</code> is |
| 43 | +indeed slash-terminated, the user supplying <code>dir</code> can only access children of |
| 44 | +<code>parent</code>, as desired. |
| 45 | + |
| 46 | +</p> |
34 | 47 |
|
35 | | -<sample src="PartialPathTraversal.java" /> |
| 48 | +<sample src="PartialPathTraversalGood.java" /> |
36 | 49 |
|
37 | 50 | </example> |
38 | 51 | <references> |
39 | 52 |
|
40 | 53 | <li> |
41 | 54 | OWASP: |
42 | | -<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>. |
| 55 | +<a href="https://owasp.org/www-community/attacks/Path_Traversal">Partial Path Traversal</a>. |
43 | 56 | </li> |
44 | 57 |
|
45 | 58 | </references> |
|
0 commit comments