-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Python: use path-injection qhelp variant employed by autofix #21308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,21 +13,27 @@ attacker being able to influence behavior by modifying unexpected files. | |
|
|
||
| <recommendation> | ||
| <p> | ||
| Validate user input before using it to construct a file path, either using an off-the-shelf library function | ||
| like <code>werkzeug.utils.secure_filename</code>, or by performing custom validation. | ||
| Validate paths constructed from untrusted user input before using them to access files. | ||
| </p> | ||
|
|
||
| <p> | ||
| Ideally, follow these rules: | ||
| The choice of validation depends on the use case. | ||
| </p> | ||
|
|
||
| <ul> | ||
| <li>Do not allow more than a single "." character.</li> | ||
| <li>Do not allow directory separators such as "/" or "\" (depending on the file system).</li> | ||
| <li>Do not rely on simply replacing problematic sequences such as "../". For example, after | ||
| applying this filter to ".../...//", the resulting string would still be "../".</li> | ||
| <li>Use an allowlist of known good patterns.</li> | ||
| </ul> | ||
| <p> | ||
| If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed | ||
| file path is contained within a safe root folder. First, normalize the path using <code>os.path.normpath</code> or | ||
| <code>os.path.realpath</code> (make sure to use the latter if symlinks are a consideration) | ||
| to remove any internal ".." segments and/or follow links. Then check that the normalized path starts with the | ||
| root folder. Note that the normalization step is important, since otherwise even a path that starts with the root | ||
| folder could be used to access files outside the root folder. | ||
| </p> | ||
|
|
||
| <p> | ||
| More restrictive options include using a library function like <code>werkzeug.utils.secure_filename</code> to eliminate | ||
| any special characters from the file path, or restricting the path to a known list of safe paths. These options are | ||
| safe, but can only be used in particular circumstances. | ||
|
Comment on lines
33
to
35
|
||
| </p> | ||
| </recommendation> | ||
|
|
||
| <example> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saying that
os.path.normpathoros.path.realpathcan be used to "remove any '..' segments" is misleading from a security perspective:normpathis purely lexical (doesn't make the path absolute or resolve symlinks) and can give a false sense of safety against traversal via symlinks within the root. Consider recommending resolving bothrootand the constructed path (for example withrealpath/Path.resolve) before performing the containment check, and clarifying the symlink caveat if you keepnormpathas an option.This issue also appears on line 24 of the same file.