Skip to content

Commit 6f3ca40

Browse files
committed
expand the explanation to include with arguments make the commands vulnerable
1 parent 8fd6424 commit 6f3ca40

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ module SecondOrderCommandInjection {
2525
or
2626
this = "hg" and exists(result)
2727
}
28+
29+
/** Gets an example argument that can cause this command to execute arbitrary code. */
30+
string getVulnerableArgumentExample() {
31+
this = "git" and result = "--upload-pack"
32+
or
33+
this = "hg" and result = "--config=alias.<alias>=<command>"
34+
}
2835
}
2936

3037
/** A source for second order command injection. */
@@ -65,6 +72,26 @@ module SecondOrderCommandInjection {
6572
abstract class Sink extends DataFlow::Node {
6673
/** Gets a label for which this is a sink. */
6774
abstract DataFlow::FlowLabel getALabel();
75+
76+
/** Gets the command getting invoked. I.e. `git` or `hg`. */
77+
abstract string getCommand();
78+
79+
/**
80+
* Gets an example argument for the comand that allows for second order command injection.
81+
* E.g. `--upload-pack` for `git`.
82+
*/
83+
abstract string getVulnerableArgumentExample();
84+
}
85+
86+
/**
87+
* A sink that invokes a command described by the `VulnerableCommand` class.
88+
*/
89+
abstract class VulnerableCommandSink extends Sink {
90+
VulnerableCommand cmd;
91+
92+
override string getCommand() { result = cmd }
93+
94+
override string getVulnerableArgumentExample() { result = cmd.getVulnerableArgumentExample() }
6895
}
6996

7097
/** A call that (indirectly) executes a shell command with a list of arguments. */
@@ -131,9 +158,9 @@ module SecondOrderCommandInjection {
131158
}
132159

133160
/** An argument to an invocation of `git`/`hg` that can cause second order command injection. */
134-
class ArgSink extends Sink {
161+
class ArgSink extends VulnerableCommandSink {
135162
ArgSink() {
136-
exists(DataFlow::ArrayCreationNode args, VulnerableCommand cmd |
163+
exists(DataFlow::ArrayCreationNode args |
137164
args = usedAsVersionControlArgs(DataFlow::TypeBackTracker::end(), _, cmd)
138165
|
139166
this = [args.getAnElement(), args.getASpreadArgument()] and
@@ -149,11 +176,9 @@ module SecondOrderCommandInjection {
149176
/**
150177
* An arguments array given to an invocation of `git` or `hg` that can cause second order command injection.
151178
*/
152-
class ArgsArraySink extends Sink {
179+
class ArgsArraySink extends VulnerableCommandSink {
153180
ArgsArraySink() {
154-
exists(SystemExecAsCmdCall exec |
155-
exec.getCommandArg().mayHaveStringValue(any(VulnerableCommand cmd))
156-
|
181+
exists(SystemExecAsCmdCall exec | exec.getCommandArg().mayHaveStringValue(cmd) |
157182
this = exec.getArgList()
158183
)
159184
}

javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import javascript
1717
import DataFlow::PathGraph
1818
import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery
1919

20-
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
21-
where cfg.hasFlowPath(source, sink)
20+
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
21+
where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode()
2222
select sink.getNode(), source, sink,
23-
"Command line argument that allows for arbitrary command execution depends on $@.",
23+
"Command line argument that depends on $@ can execute an arbitrary command if " +
24+
sinkNode.getVulnerableArgumentExample() + " is used with " + sinkNode.getCommand() + ".",
2425
source.getNode(), source.getNode().(Source).describe()

javascript/ql/test/query-tests/Security/CWE-078/SecondOrderCommandInjection/SecondOrderCommandInjection.expected

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ edges
4747
| second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote |
4848
| second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args |
4949
#select
50-
| second-order.js:7:33:7:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:7:33:7:38 | remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
51-
| second-order.js:9:29:9:34 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:9:29:9:34 | remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
52-
| second-order.js:11:33:11:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:11:33:11:38 | remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
53-
| second-order.js:15:19:15:24 | myArgs | second-order.js:13:18:13:31 | req.query.args | second-order.js:15:19:15:24 | myArgs | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:13:18:13:31 | req.query.args | a user-provided value |
54-
| second-order.js:26:35:26:40 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:26:35:26:40 | remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
55-
| second-order.js:29:19:29:32 | req.query.args | second-order.js:29:19:29:32 | req.query.args | second-order.js:29:19:29:32 | req.query.args | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:29:19:29:32 | req.query.args | a user-provided value |
56-
| second-order.js:40:28:40:43 | req.query.remote | second-order.js:40:28:40:43 | req.query.remote | second-order.js:40:28:40:43 | req.query.remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:40:28:40:43 | req.query.remote | a user-provided value |
57-
| second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:42:31:42:46 | req.query.remote | a user-provided value |
58-
| second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args | Command line argument that allows for arbitrary command execution depends on $@. | second-order.js:44:18:44:31 | req.query.args | a user-provided value |
50+
| second-order.js:7:33:7:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:7:33:7:38 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
51+
| second-order.js:9:29:9:34 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:9:29:9:34 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
52+
| second-order.js:11:33:11:38 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:11:33:11:38 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
53+
| second-order.js:15:19:15:24 | myArgs | second-order.js:13:18:13:31 | req.query.args | second-order.js:15:19:15:24 | myArgs | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:13:18:13:31 | req.query.args | a user-provided value |
54+
| second-order.js:26:35:26:40 | remote | second-order.js:6:18:6:33 | req.query.remote | second-order.js:26:35:26:40 | remote | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:6:18:6:33 | req.query.remote | a user-provided value |
55+
| second-order.js:29:19:29:32 | req.query.args | second-order.js:29:19:29:32 | req.query.args | second-order.js:29:19:29:32 | req.query.args | Command line argument that depends on $@ can execute an arbitrary command if --upload-pack is used with git. | second-order.js:29:19:29:32 | req.query.args | a user-provided value |
56+
| second-order.js:40:28:40:43 | req.query.remote | second-order.js:40:28:40:43 | req.query.remote | second-order.js:40:28:40:43 | req.query.remote | Command line argument that depends on $@ can execute an arbitrary command if --config=alias.<alias>=<command> is used with hg. | second-order.js:40:28:40:43 | req.query.remote | a user-provided value |
57+
| second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote | second-order.js:42:31:42:46 | req.query.remote | Command line argument that depends on $@ can execute an arbitrary command if --config=alias.<alias>=<command> is used with hg. | second-order.js:42:31:42:46 | req.query.remote | a user-provided value |
58+
| second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args | second-order.js:44:18:44:31 | req.query.args | Command line argument that depends on $@ can execute an arbitrary command if --config=alias.<alias>=<command> is used with hg. | second-order.js:44:18:44:31 | req.query.args | a user-provided value |

0 commit comments

Comments
 (0)