treat arrays that gets executed with shell:true as a sink for js/shell-command-constructed-from-input

This commit is contained in:
erik-krogh
2022-11-02 14:06:57 +01:00
parent bc5b7455cf
commit 40032f295a
3 changed files with 41 additions and 8 deletions

View File

@@ -156,14 +156,9 @@ module UnsafeShellCommandConstruction {
}
/**
* Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`.
* Holds if the arguments array given to `sys` is joined as a string because `shell` is set to true.
*/
private DataFlow::SourceNode endsInShellExecutedArray(
DataFlow::TypeBackTracker t, SystemCommandExecution sys
) {
t.start() and
result = sys.getArgumentList().getALocalSource() and
// the array gets joined to a string when `shell` is set to true.
predicate executesArrayAsShell(SystemCommandExecution sys) {
sys.getOptionsArg()
.getALocalSource()
.getAPropertyWrite("shell")
@@ -171,6 +166,17 @@ module UnsafeShellCommandConstruction {
.asExpr()
.(BooleanLiteral)
.getValue() = "true"
}
/**
* Gets a node that ends up in an array that is ultimately executed as a shell script by `sys`.
*/
private DataFlow::SourceNode endsInShellExecutedArray(
DataFlow::TypeBackTracker t, SystemCommandExecution sys
) {
t.start() and
result = sys.getArgumentList().getALocalSource() and
executesArrayAsShell(sys)
or
exists(DataFlow::TypeBackTracker t2 |
result = endsInShellExecutedArray(t2, sys).backtrack(t2, t)
@@ -193,6 +199,10 @@ module UnsafeShellCommandConstruction {
or
this = arr.getAMethodCall(["push", "unshift"]).getAnArgument()
)
or
this = sys.getArgumentList() and
not this instanceof DataFlow::ArrayCreationNode and
executesArrayAsShell(sys)
}
override string getSinkType() { result = "shell argument" }