|
7 | 7 | can result in sensitive information being revealed or deleted, or an attacker being able to influence
|
8 | 8 | behavior by modifying unexpected files.</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>Paths that are naively constructed from data controlled by a user may be absolute paths, or may contain |
| 11 | +unexpected special characters such as "..". Such a path could point anywhere on the file system.</p> |
12 | 12 |
|
13 | 13 | </overview>
|
14 | 14 | <recommendation>
|
15 | 15 |
|
16 |
| -<p>Validate user input before using it to construct a file path. Ideally, follow these rules:</p> |
| 16 | +<p>Validate user input before using it to construct a file path.</p> |
17 | 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>Use a whitelist of known good patterns.</li> |
24 |
| -<li>Sanitize potentially tainted paths using <code>HttpRequest.MapPath</code>.</li> |
25 |
| -</ul> |
| 18 | +<p>Common validation methods include checking that the normalized path is relative and does not contain |
| 19 | +any ".." components, or checking that the path is contained within a safe folder. The method you should use depends |
| 20 | +on how the path is used in the application, and whether the path should be a single path component. |
| 21 | +</p> |
| 22 | + |
| 23 | +<p>If the path should be a single path component (such as a file name), you can check for the existence |
| 24 | +of any path separators ("/" or "\"), or ".." sequences in the input, and reject the input if any are found. |
| 25 | +</p> |
| 26 | + |
| 27 | +<p> |
| 28 | +Note that removing "../" sequences is <i>not</i> sufficient, since the input could still contain a path separator |
| 29 | +followed by "..". For example, the input ".../...//" would still result in the string "../" if only "../" sequences |
| 30 | +are removed. |
| 31 | +</p> |
| 32 | + |
| 33 | +<p>Finally, the simplest (but most restrictive) option is to use an allow list of safe patterns and make sure that |
| 34 | +the user input matches one of these patterns.</p> |
26 | 35 |
|
27 | 36 | </recommendation>
|
28 | 37 | <example>
|
29 | 38 |
|
30 |
| -<p>In the first example, a file name is read from a <code>HttpRequest</code> and then used to access a file. However, a |
31 |
| -malicious user could enter a file name which is an absolute path - for example, "/etc/passwd". In the second example, it |
32 |
| -appears that the user is restricted to opening a file within the "user" home directory. However, a malicious user could |
33 |
| -enter a filename which contains special characters. For example, the string "../../etc/passwd" will result in the code |
34 |
| -reading the file located at "/home/[user]/../../etc/passwd", which is the system's password file. This file would then be |
35 |
| -sent back to the user, giving them access to all the system's passwords.</p> |
| 39 | +<p>In this example, a user-provided file name is read from a HTTP request and then used to access a file |
| 40 | +and send it back to the user. However, a malicious user could enter a file name anywhere on the file system, |
| 41 | +such as "/etc/passwd" or "../../../etc/passwd".</p> |
| 42 | + |
| 43 | +<sample src="examples/TaintedPath.cs" /> |
| 44 | + |
| 45 | +<p> |
| 46 | +If the input should only be a file name, you can check that it doesn't contain any path separators or ".." sequences. |
| 47 | +</p> |
| 48 | + |
| 49 | +<sample src="examples/TaintedPathGoodNormalize.cs" /> |
| 50 | + |
| 51 | +<p> |
| 52 | +If the input should be within a specific directory, you can check that the resolved path |
| 53 | +is still contained within that directory. |
| 54 | +</p> |
36 | 55 |
|
37 |
| -<sample src="TaintedPath.cs" /> |
| 56 | +<sample src="examples/TaintedPathGoodFolder.cs" /> |
38 | 57 |
|
39 | 58 | </example>
|
40 | 59 | <references>
|
|
0 commit comments