JS: add query js/indirect-command-line-injection

This commit is contained in:
Esben Sparre Andreasen
2019-05-27 11:52:35 +02:00
parent 37395877a7
commit bf4a324a86
15 changed files with 459 additions and 32 deletions

View File

@@ -17,9 +17,10 @@
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------|----------|-------------|
| | | |
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Indirect uncontrolled command line (`js/indirect-command-line-injection`) | correctness, security, external/cwe/cwe-078, external/cwe/cwe-088 | Highlights command-line invocations that may indirectly introduce a command-line injection vulnerability elsewhere, indicating a possible violation of [CWE-78](https://cwe.mitre.org/data/definitions/78.html). Results are not shown on LGTM by default. |
## Changes to existing queries

View File

@@ -7,6 +7,7 @@
+ semmlecode-javascript-queries/Security/CWE-022/TaintedPath.ql: /Security/CWE/CWE-022
+ semmlecode-javascript-queries/Security/CWE-022/ZipSlip.ql: /Security/CWE/CWE-022
+ semmlecode-javascript-queries/Security/CWE-078/CommandInjection.ql: /Security/CWE/CWE-078
+ semmlecode-javascript-queries/Security/CWE-078/IndirectCommandInjection.ql: /Security/CWE/CWE-078
+ semmlecode-javascript-queries/Security/CWE-079/ReflectedXss.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-079/StoredXss.ql: /Security/CWE/CWE-079
+ semmlecode-javascript-queries/Security/CWE-079/Xss.ql: /Security/CWE/CWE-079

View File

@@ -0,0 +1,105 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Forwarding command-line arguments to
<code>child_process.exec</code> or some other library routine that
executes a system command within a shell can change the meaning of the
command unexpectedly due to unescaped special characters.
</p>
<p>
When the forwarded command-line arguments come from a parent
process that has not escaped the special characters in the arguments,
then the parent process may indirectly be vulnerable to command-line
injection since the special characters are evaluated unexpectedly.
</p>
</overview>
<recommendation>
<p>
If possible, use hard-coded string literals to specify the
command to run or library to load. Instead of forwarding the
command-line arguments to the process, examine the command-line
arguments and then choose among hard-coded string literals.
</p>
<p>
If the applicable libraries or commands cannot be determined
at compile time, then add code to verify that each forwarded
command-line argument is properly escaped before using it.
</p>
<p>
If the forwarded command-line arguments are part of the
arguments of the system command, prefer a library routine that handles
the arguments as an array of strings rather than a single concatenated
string. This prevents the unexpected evaluation of special characters.
</p>
</recommendation>
<example>
<p>
The following wrapper script example executes another
JavaScript file in a child process and forwards some command-line
arguments. This is problematic because the special characters in the
command-line arguments may change the meaning of the child process invocation
unexpectedly. For instance, if one of the command-line arguments is
<code>"dollar$separated$name"</code>, then the child process will
substitute the two environment variables <code>$separated</code> and
<code>$name</code> before invoking <code>node</code>.
</p>
<sample src="examples/indirect-command-injection.js" />
<p>
If another program uses <code>child_process.execFile</code> to
invoke the above wrapper script with input from a remote user, then
there may be a command-line injection vulnerability.
This may be surprising, since a command-line invocation with
<code>child_process.execFile</code> is generally considered safe. But
in this case, the remote user input is simply forwarded to the
problematic <code>process.exec</code> call in the wrapper script.
</p>
<p>
To guard against this, use an API that does not perform environment
variable substitution, such as <code>child_process.execFile</code>:
</p>
<sample src="examples/indirect-command-injection_fixed.js" />
</example>
<references>
<li>
OWASP:
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,27 @@
/**
* @name Indirect uncontrolled command line
* @description Forwarding command-line arguments to a child process
* executed within a shell may indirectly introduce
* command-line injection vulnerabilities.
* @kind path-problem
* @problem.severity warning
* @precision medium
* @id js/indirect-command-line-injection
* @tags correctness
* security
* external/cwe/cwe-078
* external/cwe/cwe-088
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.IndirectCommandInjection::IndirectCommandInjection
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, DataFlow::Node highlight
where
cfg.hasFlowPath(source, sink) and
if cfg.isSinkWithHighlight(sink.getNode(), _)
then cfg.isSinkWithHighlight(sink.getNode(), highlight)
else highlight = sink.getNode()
select highlight, source, sink, "This command depends on an unsanitized $@.", source.getNode(),
"command-line argument"

View File

@@ -0,0 +1,5 @@
var cp = require("child_process");
const args = process.argv.slice(2);
const script = path.join(__dirname, 'bin', 'main.js');
cp.execSync(`node ${script} ${args.join(' ')}"`); // BAD

View File

@@ -0,0 +1,5 @@
var cp = require("child_process");
const args = process.argv.slice(2);
const script = path.join(__dirname, 'bin', 'main.js');
cp.execFileSync('node', [script].concat(args)); // GOOD

View File

@@ -23,7 +23,7 @@ private class RemoteFlowPassword extends HeuristicSource, RemoteFlowSource {
}
/**
* A use of `JSON.stringify`, viewed as a source for command line injections
* A use of `JSON.stringify`, viewed as a source for command-line injections
* since it does not properly escape single quotes and dollar symbols.
*/
private class JSONStringifyAsCommandInjectionSource extends HeuristicSource,

View File

@@ -11,6 +11,7 @@ import javascript
module CommandInjection {
import CommandInjectionCustomizations::CommandInjection
import IndirectCommandArgument
/**
* A taint-tracking configuration for reasoning about command-injection vulnerabilities.
@@ -27,7 +28,7 @@ module CommandInjection {
predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) {
sink instanceof Sink and highlight = sink
or
indirectCommandInjection(sink, highlight)
isIndirectCommandArgument(sink, highlight)
}
override predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) }
@@ -74,30 +75,4 @@ module CommandInjection {
(arg = "/c" or arg = "/C")
)
}
/**
* An indirect command execution through `sh -c` or `cmd.exe /c`.
*
* For example, we may have a call to `childProcess.spawn` like this:
*
* ```
* let sh = "sh";
* let args = ["-c", cmd];
* childProcess.spawn(sh, args, cb);
* ```
*
* Here, the indirect sink is `cmd`. For reporting purposes, however,
* we want to report the `spawn` call as the sink, so we bind it to `sys`.
*/
private predicate indirectCommandInjection(DataFlow::Node sink, SystemCommandExecution sys) {
exists(
ArgumentListTracking cfg, DataFlow::ArrayCreationNode args, ConstantString shell, string dashC
|
shellCmd(shell, dashC) and
cfg.hasFlow(DataFlow::valueNode(shell), sys.getACommandArgument()) and
cfg.hasFlow(args, sys.getArgumentList()) and
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
sink = args.getAPropertyWrite().getRhs()
)
}
}

View File

@@ -34,5 +34,4 @@ module CommandInjection {
class SystemCommandExecutionSink extends Sink, DataFlow::ValueNode {
SystemCommandExecutionSink() { this = any(SystemCommandExecution sys).getACommandArgument() }
}
}

View File

@@ -0,0 +1,71 @@
/**
* Provides predicates for reasoning about indirect command arguments.
*/
import javascript
/**
* Holds if `shell arg <cmd>` runs `<cmd>` as a shell command.
*
* That is, either `shell` is a Unix shell (`sh` or similar) and
* `arg` is `"-c"`, or `shell` is `cmd.exe` and `arg` is `"/c"`.
*/
private predicate shellCmd(ConstantString shell, string arg) {
exists(string s | s = shell.getStringValue() |
(s = "sh" or s = "bash" or s = "/bin/sh" or s = "/bin/bash") and
arg = "-c"
)
or
exists(string s | s = shell.getStringValue().toLowerCase() |
(s = "cmd" or s = "cmd.exe") and
(arg = "/c" or arg = "/C")
)
}
/**
* Data flow configuration for tracking string literals that look like they
* may refer to an operating-system shell, and array literals that may end up being
* interpreted as argument lists for system commands.
*/
private class ArgumentListTracking extends DataFlow::Configuration {
ArgumentListTracking() { this = "ArgumentListTracking" }
override predicate isSource(DataFlow::Node nd) {
nd instanceof DataFlow::ArrayCreationNode
or
exists(ConstantString shell | shellCmd(shell, _) | nd = DataFlow::valueNode(shell))
}
override predicate isSink(DataFlow::Node nd) {
exists(SystemCommandExecution sys |
nd = sys.getACommandArgument() or
nd = sys.getArgumentList()
)
}
}
/**
* Holds if `source` contributes to the arguments of an indirect command execution `sys`.
*
* An indirect command execution is a system execution command that starts with `sh -c`, `cmd.exe /c`, or similar.
*
* For example, `getCommand()` is `source`, and the call to `childProcess.spawn` is `sys` in the following example:
*
* ```
* let cmd = getCommand();
* let sh = "sh";
* let args = ["-c", cmd];
* childProcess.spawn(sh, args, cb);
* ```
*/
predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecution sys) {
exists(
ArgumentListTracking cfg, DataFlow::ArrayCreationNode args, ConstantString shell, string dashC
|
shellCmd(shell, dashC) and
cfg.hasFlow(DataFlow::valueNode(shell), sys.getACommandArgument()) and
cfg.hasFlow(args, sys.getArgumentList()) and
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
source = args.getAPropertyWrite().getRhs()
)
}

View File

@@ -0,0 +1,34 @@
/**
* Provides a taint-tracking configuration for reasoning about command-injection
* vulnerabilities (CWE-078).
*/
import javascript
module IndirectCommandInjection {
import IndirectCommandInjectionCustomizations::IndirectCommandInjection
private import IndirectCommandArgument
/**
* A taint-tracking configuration for reasoning about command-injection vulnerabilities.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "IndirectCommandInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
/**
* Holds if `sink` is a data-flow sink for command-injection vulnerabilities, and
* the alert should be placed at the node `highlight`.
*/
predicate isSinkWithHighlight(DataFlow::Node sink, DataFlow::Node highlight) {
sink instanceof Sink and highlight = sink
or
isIndirectCommandArgument(sink, highlight)
}
override predicate isSink(DataFlow::Node sink) { isSinkWithHighlight(sink, _) }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
}

View File

@@ -0,0 +1,60 @@
/**
* Provides default sources, sinks and sanitisers for reasoning about
* command-injection vulnerabilities, as well as extension points for
* adding your own.
*/
import javascript
import semmle.javascript.security.dataflow.RemoteFlowSources
module IndirectCommandInjection {
/**
* A data flow source for command-injection vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for command-injection vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for command-injection vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A source of user input from the command-line, considered as a flow source for command injection.
*/
private class CommandLineArgumentsArrayAsSource extends Source {
CommandLineArgumentsArrayAsSource() { this instanceof CommandLineArgumentsArray }
}
/**
* An array of command-line arguments.
*/
class CommandLineArgumentsArray extends DataFlow::SourceNode {
CommandLineArgumentsArray() {
this = DataFlow::globalVarRef("process").getAPropertyRead("argv")
}
}
/**
* A command-line argument that effectively is system-controlled, and therefore not likely to be exploitable when used in the execution of another command.
*/
private class SystemControlledCommandLineArgumentSanitizer extends Sanitizer {
SystemControlledCommandLineArgumentSanitizer() {
// `process.argv[0]` and `process.argv[1]` are paths to `node` and `main`.
exists(string index | index = "0" or index = "1" |
this = any(CommandLineArgumentsArray a).getAPropertyRead(index)
)
}
}
/**
* A command argument to a function that initiates an operating system command.
*/
private class SystemCommandExecutionSink extends Sink, DataFlow::ValueNode {
SystemCommandExecutionSink() { this = any(SystemCommandExecution sys).getACommandArgument() }
}
}

View File

@@ -0,0 +1,115 @@
nodes
| child_process-test.js:36:7:36:20 | sh |
| child_process-test.js:36:12:36:20 | 'cmd.exe' |
| child_process-test.js:38:7:38:20 | sh |
| child_process-test.js:38:12:38:20 | '/bin/sh' |
| child_process-test.js:39:14:39:15 | sh |
| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
| child_process-test.js:41:9:41:17 | args |
| child_process-test.js:41:16:41:17 | [] |
| child_process-test.js:44:17:44:27 | "/bin/bash" |
| child_process-test.js:44:30:44:33 | args |
| child_process-test.js:46:9:46:12 | "sh" |
| child_process-test.js:46:15:46:18 | args |
| child_process-test.js:48:9:48:17 | args |
| child_process-test.js:48:16:48:17 | [] |
| child_process-test.js:51:17:51:32 | `/bin` + "/bash" |
| child_process-test.js:51:35:51:38 | args |
| child_process-test.js:55:14:55:16 | cmd |
| child_process-test.js:55:19:55:22 | args |
| child_process-test.js:56:12:56:14 | cmd |
| child_process-test.js:56:17:56:20 | args |
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv |
| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] |
| command-line-parameter-command-injection.js:8:22:8:33 | process.argv |
| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] |
| command-line-parameter-command-injection.js:10:6:10:33 | args |
| command-line-parameter-command-injection.js:10:13:10:24 | process.argv |
| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) |
| command-line-parameter-command-injection.js:11:14:11:17 | args |
| command-line-parameter-command-injection.js:11:14:11:20 | args[0] |
| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] |
| command-line-parameter-command-injection.js:12:26:12:29 | args |
| command-line-parameter-command-injection.js:12:26:12:32 | args[0] |
| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs |
| command-line-parameter-command-injection.js:14:18:14:21 | args |
| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) |
| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs |
| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] |
| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] |
| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs |
| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] |
| command-line-parameter-command-injection.js:18:6:18:24 | arg0 |
| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs |
| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] |
| command-line-parameter-command-injection.js:19:14:19:17 | arg0 |
| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 |
| command-line-parameter-command-injection.js:20:26:20:29 | arg0 |
| command-line-parameter-command-injection.js:24:8:24:35 | args |
| command-line-parameter-command-injection.js:24:15:24:26 | process.argv |
| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) |
| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` |
| command-line-parameter-command-injection.js:26:32:26:35 | args |
| command-line-parameter-command-injection.js:26:32:26:38 | args[0] |
| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` |
| command-line-parameter-command-injection.js:27:32:27:35 | args |
| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') |
edges
| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:5:39:5 | sh |
| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:14:39:15 | sh |
| child_process-test.js:36:12:36:20 | 'cmd.exe' | child_process-test.js:36:7:36:20 | sh |
| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:5:39:5 | sh |
| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:14:39:15 | sh |
| child_process-test.js:38:12:38:20 | '/bin/sh' | child_process-test.js:38:7:38:20 | sh |
| child_process-test.js:39:5:39:5 | sh | child_process-test.js:39:14:39:15 | sh |
| child_process-test.js:41:9:41:17 | args | child_process-test.js:44:30:44:33 | args |
| child_process-test.js:41:9:41:17 | args | child_process-test.js:46:15:46:18 | args |
| child_process-test.js:41:16:41:17 | [] | child_process-test.js:41:9:41:17 | args |
| child_process-test.js:46:9:46:12 | "sh" | child_process-test.js:55:14:55:16 | cmd |
| child_process-test.js:46:15:46:18 | args | child_process-test.js:55:19:55:22 | args |
| child_process-test.js:48:9:48:17 | args | child_process-test.js:51:35:51:38 | args |
| child_process-test.js:48:16:48:17 | [] | child_process-test.js:48:9:48:17 | args |
| child_process-test.js:55:14:55:16 | cmd | child_process-test.js:56:12:56:14 | cmd |
| child_process-test.js:55:19:55:22 | args | child_process-test.js:56:17:56:20 | args |
| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] |
| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] |
| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args |
| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args |
| command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args |
| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) |
| command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args |
| command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] |
| command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:26:12:32 | args[0] |
| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] |
| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs |
| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs |
| command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs |
| command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) |
| command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs |
| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] |
| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] |
| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] |
| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 |
| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 |
| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] |
| command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 |
| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 |
| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args |
| command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args |
| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) |
| command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args |
| command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:32:26:38 | args[0] |
| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` |
| command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') |
| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` |
#select
| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:19:14:19:17 | arg0 | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line argument |
| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line argument |

View File

@@ -0,0 +1 @@
Security/CWE-078/IndirectCommandInjection.ql

View File

@@ -0,0 +1,28 @@
var cp = require("child_process");
(function() {
cp.exec(process.argv); // NOT OK (just weird)
cp.exec(process.argv[0]); // OK
cp.exec("cmd.sh " + process.argv[0]); // OK
cp.exec("cmd.sh " + process.argv[1]); // OK
cp.exec("cmd.sh " + process.argv[2]); // NOT OK
var args = process.argv.slice(2);
cp.execSync(args[0]); // NOT OK
cp.execSync("cmd.sh " + args[0]); // NOT OK
var fewerArgs = args.slice(1);
cp.execSync(fewerArgs[0]); // NOT OK
cp.execSync("cmd.sh " + fewerArgs[0]); // NOT OK
var arg0 = fewerArgs[0];
cp.execSync(arg0); // OK
cp.execSync("cmd.sh " + arg0); // NOT OK
});
(function() {
const args = process.argv.slice(2);
const script = path.join(packageDir, 'app', 'index.js');
cp.execSync(`node ${script} ${args[0]} --option"`); // NOT OK
cp.execSync(`node ${script} ${args.join(' ')} --option"`); // NOT OK
});