77 * query.
88 */
99
10- import semmle.code.java.dataflow.FlowSources
11- import semmle.code.java.security.ExternalProcess
12- import semmle.code.java.security.CommandArguments
10+ import java
11+ private import semmle.code.java.dataflow.FlowSources
12+ private import semmle.code.java.dataflow.ExternalFlow
13+ private import semmle.code.java.security.ExternalProcess
14+ private import semmle.code.java.security.CommandArguments
15+
16+ /** A sink for command injection vulnerabilities. */
17+ abstract class CommandInjectionSink extends DataFlow:: Node { }
18+
19+ /** A sanitizer for command injection vulnerabilities. */
20+ abstract class CommandInjectionSanitizer extends DataFlow:: Node { }
1321
1422/**
15- * DEPRECATED: Use `RemoteUserInputToArgumentToExecFlow` instead .
23+ * A unit class for adding additional taint steps .
1624 *
17- * A taint-tracking configuration for unvalidated user input that is used to run an external process .
25+ * Extend this class to add additional taint steps that should apply to configurations related to command injection .
1826 */
19- deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking:: Configuration {
20- RemoteUserInputToArgumentToExecFlowConfig ( ) {
21- this = "ExecCommon::RemoteUserInputToArgumentToExecFlowConfig"
22- }
23-
24- override predicate isSource ( DataFlow:: Node src ) { src instanceof RemoteFlowSource }
27+ class CommandInjectionAdditionalTaintStep extends Unit {
28+ /**
29+ * Holds if the step from `node1` to `node2` should be considered a taint
30+ * step for configurations related to command injection.
31+ */
32+ abstract predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) ;
33+ }
2534
26- override predicate isSink ( DataFlow:: Node sink ) { sink .asExpr ( ) instanceof ArgumentToExec }
35+ private class DefaultCommandInjectionSink extends CommandInjectionSink {
36+ DefaultCommandInjectionSink ( ) {
37+ this .asExpr ( ) instanceof ArgumentToExec or sinkNode ( this , "command-injection" )
38+ }
39+ }
2740
28- override predicate isSanitizer ( DataFlow:: Node node ) {
29- node .getType ( ) instanceof PrimitiveType
41+ private class DefaultCommandInjectionSanitizer extends CommandInjectionSanitizer {
42+ DefaultCommandInjectionSanitizer ( ) {
43+ this .getType ( ) instanceof PrimitiveType
3044 or
31- node .getType ( ) instanceof BoxedType
45+ this .getType ( ) instanceof BoxedType
3246 or
33- isSafeCommandArgument ( node .asExpr ( ) )
47+ isSafeCommandArgument ( this .asExpr ( ) )
3448 }
3549}
3650
@@ -40,14 +54,12 @@ deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking
4054module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow:: ConfigSig {
4155 predicate isSource ( DataFlow:: Node src ) { src instanceof RemoteFlowSource }
4256
43- predicate isSink ( DataFlow:: Node sink ) { sink . asExpr ( ) instanceof ArgumentToExec }
57+ predicate isSink ( DataFlow:: Node sink ) { sink instanceof CommandInjectionSink }
4458
45- predicate isBarrier ( DataFlow:: Node node ) {
46- node .getType ( ) instanceof PrimitiveType
47- or
48- node .getType ( ) instanceof BoxedType
49- or
50- isSafeCommandArgument ( node .asExpr ( ) )
59+ predicate isBarrier ( DataFlow:: Node node ) { node instanceof CommandInjectionSanitizer }
60+
61+ predicate isAdditionalFlowStep ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
62+ any ( CommandInjectionAdditionalTaintStep s ) .step ( n1 , n2 )
5163 }
5264}
5365
@@ -58,29 +70,48 @@ module RemoteUserInputToArgumentToExecFlow =
5870 TaintTracking:: Global< RemoteUserInputToArgumentToExecFlowConfig > ;
5971
6072/**
61- * DEPRECATED: Use `execIsTainted` instead.
62- *
6373 * Implementation of `ExecTainted.ql`. It is extracted to a QLL
6474 * so that it can be excluded from `ExecUnescaped.ql` to avoid
6575 * reporting overlapping results.
6676 */
67- deprecated predicate execTainted (
68- DataFlow:: PathNode source , DataFlow:: PathNode sink , ArgumentToExec execArg
77+ predicate execIsTainted (
78+ RemoteUserInputToArgumentToExecFlow:: PathNode source ,
79+ RemoteUserInputToArgumentToExecFlow:: PathNode sink , Expr execArg
6980) {
70- exists ( RemoteUserInputToArgumentToExecFlowConfig conf |
71- conf .hasFlowPath ( source , sink ) and sink .getNode ( ) = DataFlow:: exprNode ( execArg )
72- )
81+ RemoteUserInputToArgumentToExecFlow:: flowPath ( source , sink ) and
82+ sink .getNode ( ) .asExpr ( ) = execArg
7383}
7484
7585/**
86+ * DEPRECATED: Use `execIsTainted` instead.
87+ *
7688 * Implementation of `ExecTainted.ql`. It is extracted to a QLL
7789 * so that it can be excluded from `ExecUnescaped.ql` to avoid
7890 * reporting overlapping results.
7991 */
80- predicate execIsTainted (
81- RemoteUserInputToArgumentToExecFlow:: PathNode source ,
82- RemoteUserInputToArgumentToExecFlow:: PathNode sink , ArgumentToExec execArg
83- ) {
84- RemoteUserInputToArgumentToExecFlow:: flowPath ( source , sink ) and
85- sink .getNode ( ) = DataFlow:: exprNode ( execArg )
92+ deprecated predicate execTainted ( DataFlow:: PathNode source , DataFlow:: PathNode sink , Expr execArg ) {
93+ exists ( RemoteUserInputToArgumentToExecFlowConfig conf |
94+ conf .hasFlowPath ( source , sink ) and sink .getNode ( ) .asExpr ( ) = execArg
95+ )
96+ }
97+
98+ /**
99+ * DEPRECATED: Use `RemoteUserInputToArgumentToExecFlow` instead.
100+ *
101+ * A taint-tracking configuration for unvalidated user input that is used to run an external process.
102+ */
103+ deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking:: Configuration {
104+ RemoteUserInputToArgumentToExecFlowConfig ( ) {
105+ this = "ExecCommon::RemoteUserInputToArgumentToExecFlowConfig"
106+ }
107+
108+ override predicate isSource ( DataFlow:: Node src ) { src instanceof RemoteFlowSource }
109+
110+ override predicate isSink ( DataFlow:: Node sink ) { sink instanceof CommandInjectionSink }
111+
112+ override predicate isSanitizer ( DataFlow:: Node node ) { node instanceof CommandInjectionSanitizer }
113+
114+ override predicate isAdditionalTaintStep ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
115+ any ( CommandInjectionAdditionalTaintStep s ) .step ( n1 , n2 )
116+ }
86117}
0 commit comments