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
Python : Add sanitizers for Path Injection Query #7009
base: main
Are you sure you want to change the base?
Conversation
This PR adds a few sanitizers to the exisitng Path injection query.
| */ | ||
| private class OsPathAbsoluteCallAsSanitizer extends Sanitizer { | ||
| OsPathAbsoluteCallAsSanitizer() { | ||
| this = API::moduleImport("os").getMember("path").getMember("abspath").getACall().getArg(_) |
I might be wrong, but isn't this saying that the argument to abspath has been sanitized?
Don't we instead want to say that the result of such a call has been sanitized?
(EDIT: I misunderstood how abspath works in this case. Only the combination of abspath and checking whether it starts with a specific prefix should be considered a sanitizer-guard)
So in this example:
sanitizedPath = os.path.abspath(taintedPath)
dangerousUse(taintedPath)taintedPath could not flow to dangerousUse because it is used once as an argument to abspath and therefore considered sanitized (which is not correct).
If I'm right you could add new tests that show the improvements of this PR.
I considered it when writing this PR. Yes, what you are saying is true. But consider the case here. https://github.com/kizniche/Mycodo/blob/6c0d710c8138aa06e6dcd909097854afe0d5cebe/mycodo/mycodo_flask/routes_general.py#L120-L121
In this case, since file_path is checked earlier, the code is not exploitable. So I thought it would be best to avoid multiple FPs and accept a reduced TP count instead.
|
@RasmusWL The query currently flags some sinks which shouldn't otherwise be there. For ex, a simple run of the query with the proposed changes included leads to 3 results. Of which 2 of them are calls to |
This PR goes against how we deal with path injection. You should NOT change the query.
abspath is already modeled, see
codeql/python/ql/lib/semmle/python/frameworks/Stdlib.qll
Lines 303 to 311 in 8b6baa2
| /** | |
| * A call to `os.path.abspath`. | |
| * See https://docs.python.org/3/library/os.path.html#os.path.abspath | |
| */ | |
| private class OsPathAbspathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode { | |
| OsPathAbspathCall() { this = os::path().getMember("abspath").getACall() } | |
| DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] } | |
| } |
and .startswith is already modeled:
codeql/python/ql/lib/semmle/python/frameworks/Stdlib.qll
Lines 1757 to 1768 in 8b6baa2
| /** | |
| * A call to the `startswith` method on a string. | |
| * See https://docs.python.org/3.9/library/stdtypes.html#str.startswith | |
| */ | |
| private class StartswithCall extends Path::SafeAccessCheck::Range { | |
| StartswithCall() { this.(CallNode).getFunction().(AttrNode).getName() = "startswith" } | |
| override predicate checks(ControlFlowNode node, boolean branch) { | |
| node = this.(CallNode).getFunction().(AttrNode).getObject() and | |
| branch = true | |
| } | |
| } |
So all in all, I'm surprised this isn't handled properly already.
As a first step, can you please update the query test file to include the new case (FP) that you want to handle better (remember to update the .expected files).
Then we will need to figure out why the current modeling doesn't work.
|
(I didn't notice this reply at first)
@porcupineyhairs can you please add tests with these cases? I'm not able to imagine what these FPs looks like based on just that text |
|
@RasmusWL I have added the tests now. These are based on kizniche/Mycodo Also, there are sinks which we are not detected by the query but which otherwise should have been included there eg. |
| def camera_img_acquire(filename): | ||
| filename = request.args.get('filename', '') | ||
| image_path = os.path.join(STATIC_DIR, filename) | ||
| if not os.path.exists(image_path): # OK as exposure of ctime of a particular file does not pose a security thread |
This PR adds a few sanitizers to the exisitng Path injection query.
The text was updated successfully, but these errors were encountered: