@@ -13,21 +13,27 @@ attacker being able to influence behavior by modifying unexpected files.
1313
1414<recommendation >
1515<p >
16- Validate user input before using it to construct a file path, either using an off-the-shelf library function
17- like <code >werkzeug.utils.secure_filename</code >, or by performing custom validation.
16+ Validate paths constructed from untrusted user input before using them to access files.
1817</p >
1918
2019<p >
21- Ideally, follow these rules:
20+ The choice of validation depends on the use case.
2221</p >
2322
24- <ul >
25- <li >Do not allow more than a single "." character.</li >
26- <li >Do not allow directory separators such as "/" or "\" (depending on the file system).</li >
27- <li >Do not rely on simply replacing problematic sequences such as "../". For example, after
28- applying this filter to ".../...//", the resulting string would still be "../".</li >
29- <li >Use an allowlist of known good patterns.</li >
30- </ul >
23+ <p >
24+ If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed
25+ file path is contained within a safe root folder. First, normalize the path using <code >os.path.normpath</code > or
26+ <code >os.path.realpath</code > (make sure to use the latter if symlinks are a consideration)
27+ to remove any internal ".." segments and/or follow links. Then check that the normalized path starts with the
28+ root folder. Note that the normalization step is important, since otherwise even a path that starts with the root
29+ folder could be used to access files outside the root folder.
30+ </p >
31+
32+ <p >
33+ More restrictive options include using a library function like <code >werkzeug.utils.secure_filename</code > to eliminate
34+ any special characters from the file path, or restricting the path to a known list of safe paths. These options are
35+ safe, but can only be used in particular circumstances.
36+ </p >
3137</recommendation >
3238
3339<example >
0 commit comments