mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
JS: add query js/indirect-command-line-injection
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,5 +34,4 @@ module CommandInjection {
|
||||
class SystemCommandExecutionSink extends Sink, DataFlow::ValueNode {
|
||||
SystemCommandExecutionSink() { this = any(SystemCommandExecution sys).getACommandArgument() }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
@@ -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() }
|
||||
}
|
||||
}
|
||||
@@ -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 |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE-078/IndirectCommandInjection.ql
|
||||
@@ -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
|
||||
});
|
||||
Reference in New Issue
Block a user