Skip to content

Conversation

erik-krogh
Copy link
Contributor

@erik-krogh erik-krogh commented Jan 31, 2023

The query is almost direct copy-paste from Ruby.
The query doesn't (currently) flag any CVEs, but that will hopefully happen in the future.

Evaluation looks OK.
Shows a slight slowdown from adding a new query, but I can't find a reason for the slowdown when I try locally.

Full MRVA run.

Many of the results are just 🤦 without being security relevant, but they are bad enough style that I think the results are OK regardless of whether it's a security issue.

The results in localstack are FPs, due to it spuriously finding that shell can be set to True. But I don't think we can fix that.
Lots of the results are file paths inserted into shell strings.

@erik-krogh erik-krogh added the WIP This is a work-in-progress, do not merge yet! label Jan 31, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Jan 31, 2023

QHelp previews:

python/ql/src/Security/CWE-078/UnsafeShellCommandConstruction.qhelp

Unsafe shell command constructed from library input

Dynamically constructing a shell command with inputs from library functions may inadvertently change the meaning of the shell command. Clients using the exported function may use inputs containing characters that the shell interprets in a special way, for instance quotes and spaces. This can result in the shell command misbehaving, or even allowing a malicious user to execute arbitrary commands on the system.

Recommendation

If possible, provide the dynamic arguments to the shell as an array to APIs such as subprocess.run to avoid interpretation by the shell.

Alternatively, if the shell command must be constructed dynamically, then add code to ensure that special characters do not alter the shell command unexpectedly.

Example

The following example shows a dynamically constructed shell command that downloads a file from a remote URL.

import os

def download(path): 
    os.system("wget " + path) # NOT OK

The shell command will, however, fail to work as intended if the input contains spaces or other special characters interpreted in a special way by the shell.

Even worse, a client might pass in user-controlled data, not knowing that the input is interpreted as a shell command. This could allow a malicious user to provide the input http://example.org; cat /etc/passwd in order to execute the command cat /etc/passwd.

To avoid such potentially catastrophic behaviors, provide the input from library functions as an argument that does not get interpreted by a shell:

import subprocess

def download(path): 
    subprocess.run(["wget", path]) # OK

References

@erik-krogh erik-krogh force-pushed the py-shell branch 4 times, most recently from c685cfc to 6c2f5ed Compare February 1, 2023 23:14
@erik-krogh erik-krogh removed the WIP This is a work-in-progress, do not merge yet! label Feb 3, 2023
Comment on lines +40 to +53
/**
* Gets an AST node that is exported by a library.
*/
private AstNode getAnExportedLibraryFeature() {
result.(Module).getFile() = getALibraryExportedContainer()
or
result = getAnExportedLibraryFeature().(Module).getAStmt()
or
result = getAnExportedLibraryFeature().(ClassDef).getDefinedClass().getAMethod()
or
result = getAnExportedLibraryFeature().(ClassDef).getDefinedClass().getInitMethod()
or
result = getAnExportedLibraryFeature().(FunctionDef).getDefinedFunction()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The equivalent predicate in JavaScript is way bigger, with more cases in the disjunction.

I imagine this will grow over time, but for now I'll start with what I've seen a need for.

@erik-krogh erik-krogh marked this pull request as ready for review February 3, 2023 14:02
@erik-krogh erik-krogh requested a review from a team as a code owner February 3, 2023 14:02
@calumgrant calumgrant requested a review from RasmusWL February 6, 2023 10:32
Copy link
Member

@RasmusWL RasmusWL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, thanks 👍 I would like to see a few minor changes, and then we need to discuss the precision of the query a bit 👍

* @kind path-problem
* @problem.severity error
* @security-severity 6.3
* @precision high
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's talk a bit more about what the precision should be.

Many of the results are just 🤦 without being security relevant, but they are bad enough style that I think the results are OK regardless of whether it's a security issue.

This ☝️ part of your PR comment makes it sound like most of the results are following a bad pattern that ideally should be fixed. But also that it's like it is a code smell and not a security issue.

Based on that, I'm thinking it might be more appropriate to use @precision medium, but happy to hear your thoughts on this.

(I looked over some of the MRVA results, but most of the ones I looked at seemed "meh" to me)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a code-smell with high precision, but a security issue with medium precision.

So I suggest that we lower the severity to warning instead of lowering the precision.
Thoughts?

@erik-krogh erik-krogh requested a review from RasmusWL February 20, 2023 10:36
@erik-krogh erik-krogh merged commit 04f422e into github:main Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants