@@ -10,6 +10,8 @@ private import semmle.javascript.security.TaintedObjectCustomizations
1010
1111/** Classes and predicates for reasoning about second order command injection. */
1212module SecondOrderCommandInjection {
13+ import semmle.javascript.security.CommonFlowState
14+
1315 /** A shell command that allows for second order command injection. */
1416 private class VulnerableCommand extends string {
1517 VulnerableCommand ( ) { this = [ "git" , "hg" ] }
@@ -39,8 +41,11 @@ module SecondOrderCommandInjection {
3941 /** Gets a string that describes the source. For use in the alert message. */
4042 abstract string describe ( ) ;
4143
42- /** Gets a label for which this is a source. */
43- abstract DataFlow:: FlowLabel getALabel ( ) ;
44+ /** Gets a flow state for which this is a source. */
45+ FlowState getAFlowState ( ) { result .isTaint ( ) }
46+
47+ /** DEPRECATED. Use `getAFlowState()` instead */
48+ deprecated DataFlow:: FlowLabel getALabel ( ) { result = this .getAFlowState ( ) .toFlowLabel ( ) }
4449 }
4550
4651 /** A parameter of an exported function, seen as a source for second order command injection. */
@@ -49,18 +54,18 @@ module SecondOrderCommandInjection {
4954
5055 override string describe ( ) { result = "library input" }
5156
52- override DataFlow :: FlowLabel getALabel ( ) { result = TaintedObject :: label ( ) or result .isTaint ( ) }
57+ override FlowState getAFlowState ( ) { result . isTaintedObject ( ) or result .isTaint ( ) }
5358 }
5459
5560 /** A source of remote flow, seen as a source for second order command injection. */
5661 class RemoteFlowAsSource extends Source instanceof RemoteFlowSource {
5762 override string describe ( ) { result = "a user-provided value" }
5863
59- override DataFlow :: FlowLabel getALabel ( ) { result .isTaint ( ) }
64+ override FlowState getAFlowState ( ) { result .isTaint ( ) }
6065 }
6166
6267 private class TaintedObjectSourceAsSource extends Source instanceof TaintedObject:: Source {
63- override DataFlow :: FlowLabel getALabel ( ) { result = TaintedObject :: label ( ) }
68+ override FlowState getAFlowState ( ) { result . isTaintedObject ( ) }
6469
6570 override string describe ( ) { result = "a user-provided value" }
6671 }
@@ -70,8 +75,11 @@ module SecondOrderCommandInjection {
7075
7176 /** A sink for second order command injection. */
7277 abstract class Sink extends DataFlow:: Node {
73- /** Gets a label for which this is a sink. */
74- abstract DataFlow:: FlowLabel getALabel ( ) ;
78+ /** Gets a flow state for which this is a sink. */
79+ FlowState getAFlowState ( ) { result .isTaint ( ) or result .isTaintedObject ( ) }
80+
81+ /** DERECATED. Use `getAFlowState()` instead. */
82+ deprecated DataFlow:: FlowLabel getALabel ( ) { result = this .getAFlowState ( ) .toFlowLabel ( ) }
7583
7684 /** Gets the command getting invoked. I.e. `git` or `hg`. */
7785 abstract string getCommand ( ) ;
@@ -93,16 +101,16 @@ module SecondOrderCommandInjection {
93101 predicate blocksExpr ( boolean outcome , Expr e ) { none ( ) }
94102
95103 /**
96- * Holds if this node acts as a barrier for `label `, blocking further flow from `e` if `this` evaluates to `outcome`.
104+ * Holds if this node acts as a barrier for `state `, blocking further flow from `e` if `this` evaluates to `outcome`.
97105 */
98- predicate blocksExpr ( boolean outcome , Expr e , DataFlow :: FlowLabel label ) { none ( ) }
106+ predicate blocksExpr ( boolean outcome , Expr e , FlowState state ) { none ( ) }
99107
100108 /** DEPRECATED. Use `blocksExpr` instead. */
101109 deprecated predicate sanitizes ( boolean outcome , Expr e ) { this .blocksExpr ( outcome , e ) }
102110
103111 /** DEPRECATED. Use `blocksExpr` instead. */
104112 deprecated predicate sanitizes ( boolean outcome , Expr e , DataFlow:: FlowLabel label ) {
105- this .blocksExpr ( outcome , e , label )
113+ this .blocksExpr ( outcome , e , FlowState :: fromFlowLabel ( label ) )
106114 }
107115 }
108116
@@ -205,7 +213,7 @@ module SecondOrderCommandInjection {
205213 )
206214 }
207215
208- override DataFlow :: FlowLabel getALabel ( ) { result .isTaint ( ) }
216+ override FlowState getAFlowState ( ) { result .isTaint ( ) }
209217 }
210218
211219 /**
@@ -219,7 +227,7 @@ module SecondOrderCommandInjection {
219227 }
220228
221229 // only vulnerable if an attacker controls the entire array
222- override DataFlow :: FlowLabel getALabel ( ) { result = TaintedObject :: label ( ) }
230+ override FlowState getAFlowState ( ) { result . isTaintedObject ( ) }
223231 }
224232
225233 /**
0 commit comments