@@ -13,27 +13,36 @@ such as "..". Such a path may potentially point to any directory on the file sys
1313</overview >
1414<recommendation >
1515
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 >
1717
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 >
18+ <p >The choice of validation depends on the use case.</p >
19+
20+ <p >If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed
21+ file path is contained within a safe root folder, for example by checking that the path starts with the root folder.
22+ Additionally, you need to ensure that the path does not contain any ".." components, since these would allow
23+ the path to escape the root folder.</p >
24+
25+ <p >A safer (but more restrictive) option is to use an allow list of safe paths and make sure that
26+ the user input is one of those paths.</p >
2527
2628</recommendation >
2729<example >
2830
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 >
31+ <p >In this example, a file name is read from a <code >java.net.Socket</code > and then used to access a file
32+ and send it back over the socket. However, a malicious user could enter a file name anywhere on the file system,
33+ such as "/etc/passwd".</p >
3434
3535<sample src =" TaintedPath.java" />
3636
37+ <p >Simply checking that the path is under a trusted location (such as the user's home directory) is not enough,
38+ however, since the path could contain relative components such as "..". For example, the string
39+ "/home/[user]/../../etc/passwd" starts with the user's home directory, but would still result in the code reading
40+ the file located at "/etc/passwd".</p >
41+
42+ <p >To fix this, we check that the user-provided path does not contain ".." and starts with the user's home directory.</p >
43+
44+ <sample src =" TaintedPathGood.java" />
45+
3746</example >
3847<references >
3948
0 commit comments