-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Java: Experimental version of Java Command Injection query #13484
Java: Experimental version of Java Command Injection query #13484
Conversation
…e sensitive to unusual code constructs
QHelp previews: java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qhelpCommand Injection into Runtime.exec() with dangerous commandCode that passes remote user input to an arugment of a call of RecommendationIf possible, use hard-coded string literals to specify the command or script to run, or library to load. Instead of passing the user input directly to the process or library function, examine the user input and then choose among hard-coded string literals. If the applicable libraries or commands cannot be determined at compile time, then add code to verify that the user input string is safe before using it. ExampleThe following example shows code that takes a shell script that can be changed maliciously by a user, and passes it straight to the array going into class Test {
public static void main(String[] args) {
String script = System.getenv("SCRIPTNAME");
if (script != null) {
// BAD: The script to be executed by /bin/sh is controlled by the user.
Runtime.getRuntime().exec(new String[]{"/bin/sh", script});
}
}
} References
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecLocal.qhelpCommand Injection into Runtime.exec() with dangerous commandCode that passes local user input to an arugment of a call of RecommendationIf possible, use hard-coded string literals to specify the command or script to run, or library to load. Instead of passing the user input directly to the process or library function, examine the user input and then choose among hard-coded string literals. If the applicable libraries or commands cannot be determined at compile time, then add code to verify that the user input string is safe before using it. ExampleThe following example shows code that takes a shell script that can be changed maliciously by a user, and passes it straight to the array going into class Test {
public static void main(String[] args) {
String script = System.getenv("SCRIPTNAME");
if (script != null) {
// BAD: The script to be executed by /bin/sh is controlled by the user.
Runtime.getRuntime().exec(new String[]{"/bin/sh", script});
}
}
} References
|
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.ql
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecLocal.ql
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.ql
Fixed
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.md
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecTest.ql
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.ql
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecLocal.ql
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qll
Show resolved
Hide resolved
I've made all of the changes you suggested @atorralba, except for the varargs one - as I commented above, I don't think I'm failing to get it to pass the "compile all queries" check, since it thinks the formatting isn't correct. I've run the QL formatter in VSCode, so I'm not sure what's wrong. |
Hey @aegilops, thanks for being so thorough, and you're absolutely right about the varargs thing, I was over-engineering. I pushed a commit with the formatting changes (my VSCode did format it right 🤷), happy to approve this after you |
Lots of green ticks ✅, I like the look of that I spoke too soon, running the whole Java suite take a while! Now we have all green... |
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.
Removing some (I think!) Emacs comments, otherwise LGTM :)
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecLocal.qhelp
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExec.qhelp
Outdated
Show resolved
Hide resolved
java/ql/src/experimental/Security/CWE/CWE-078/CommandInjectionRuntimeExecLocal.ql
Outdated
Show resolved
Hide resolved
Otherwise they would both apply at the same time, making both versions of the query identical.
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.
Thanks for your patience @aegilops!
This query is designed to be more sensitive than the existing CodeQL query,
java/command-line-injection
.There is a specific GitHub Advanced Security customer who wants this query.
For the case where a dangerous executable is used, such as
/bin/sh
, the original query tries to determine that the string ends up in the first element of the array used in the call toexec
.In some unusual cases, the approach used cannot track the connection between the static string and its position as the first element of the array, e.g.
Instead of trying to tell that
/bin/sh
is in argument 0, we can rule out that it can be anywhere other than 0, which is the approach that this query takes. It is also aware ofStream.concat
.I have some unit tests, but wasn't sure where to put them in the "experimental" hierarchy!