@@ -15,24 +15,27 @@ import java
15
15
import semmle.code.java.dataflow.FlowSources
16
16
import semmle.code.java.dataflow.TaintTracking2
17
17
import semmle.code.java.security.XSS
18
- import DataFlow:: PathGraph
19
18
import semmle.code.java.frameworks.Servlets
20
19
import JSPLocations
21
20
22
- class XSSConfig extends TaintTracking:: Configuration {
23
- XSSConfig ( ) { this = "XSSConfig" }
21
+ module Xss {
22
+ module XssConfig implements DataFlow:: ConfigSig {
23
+ predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
24
24
25
- override predicate isSource ( DataFlow:: Node source ) { source instanceof RemoteFlowSource }
25
+ predicate isSink ( DataFlow:: Node sink ) { sink instanceof XssSink }
26
26
27
- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof XssSink }
27
+ predicate isBarrier ( DataFlow:: Node node ) { node instanceof XssSanitizer }
28
28
29
- override predicate isSanitizer ( DataFlow:: Node node ) { node instanceof XssSanitizer }
29
+ predicate isBarrierOut ( DataFlow:: Node node ) { node instanceof XssSinkBarrier }
30
30
31
- override predicate isSanitizerOut ( DataFlow:: Node node ) { node instanceof XssSinkBarrier }
32
-
33
- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
34
- any ( XssAdditionalTaintStep s ) .step ( node1 , node2 )
31
+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
32
+ any ( XssAdditionalTaintStep s ) .step ( node1 , node2 )
33
+ }
35
34
}
35
+
36
+ module XssFlow = TaintTracking:: Global< XssConfig > ;
37
+
38
+ import XssFlow:: PathGraph
36
39
}
37
40
38
41
// additional sources: Consider return values of ServletRequest methods to be tainted (potentially noisy)
@@ -124,10 +127,13 @@ class ForEachStep extends XssAdditionalTaintStep {
124
127
override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
125
128
exists ( Variable v , string varName , EvalCall eval |
126
129
v .getType ( ) .getName ( ) = "ForEachTag" and
127
- exists ( ContextFlowConfig config , DataFlow:: Node ctxSrc |
128
- config
129
- .hasFlow ( ctxSrc , DataFlow2:: exprNode ( methodCallOn ( "setPageContext" , v ) .getArgument ( 0 ) ) ) and
130
- config .hasFlow ( ctxSrc , DataFlow2:: exprNode ( eval .getCtxExpr ( ) ) )
130
+ exists ( DataFlow:: Node ctxSrc |
131
+ ContextFlow:: ContextFlow:: flow ( ctxSrc ,
132
+ DataFlow2:: exprNode ( methodCallOn ( "setPageContext" , v ) .getArgument ( 0 ) ) ) and
133
+ ContextFlow:: ContextFlow:: flow ( ctxSrc , DataFlow2:: exprNode ( eval .getCtxExpr ( ) ) )
134
+ // config
135
+ // .hasFlow(ctxSrc, DataFlow2::exprNode(methodCallOn("setPageContext", v).getArgument(0))) and
136
+ // config.hasFlow(ctxSrc, DataFlow2::exprNode(eval.getCtxExpr()))
131
137
) and
132
138
node1 .asExpr ( ) = methodCallOn ( "setItems" , v ) .getArgument ( 0 ) and
133
139
node2 .asExpr ( ) = eval and
@@ -137,41 +143,49 @@ class ForEachStep extends XssAdditionalTaintStep {
137
143
}
138
144
}
139
145
140
- class LiteralConfig extends TaintTracking2:: Configuration {
141
- LiteralConfig ( ) { this = "LiteralConfig" }
142
-
143
- override predicate isSource ( DataFlow2:: Node source ) { source .asExpr ( ) instanceof StringLiteral }
146
+ module LiteralConfig {
147
+ module LiteralConfig implements DataFlow:: ConfigSig {
148
+ predicate isSource ( DataFlow:: Node source ) { source .asExpr ( ) instanceof StringLiteral }
144
149
145
- override predicate isSink ( DataFlow2:: Node sink ) {
146
- exists ( ReturnStmt rs | rs .getResult ( ) = sink .asExpr ( ) )
150
+ predicate isSink ( DataFlow:: Node sink ) { exists ( ReturnStmt rs | rs .getResult ( ) = sink .asExpr ( ) ) }
147
151
}
152
+
153
+ module LiteralFlow = TaintTracking:: Global< LiteralConfig > ;
154
+
155
+ import LiteralFlow:: PathGraph
148
156
}
149
157
150
- class ContextFlowConfig extends TaintTracking2:: Configuration {
151
- ContextFlowConfig ( ) { this = "ContextFlowConfig" }
158
+ module ContextFlow {
159
+ module ContextFlowConfig implements DataFlow:: ConfigSig {
160
+ predicate isSource ( DataFlow:: Node source ) {
161
+ source .asExpr ( ) .getType ( ) .getName ( ) = "PageContext"
162
+ }
152
163
153
- override predicate isSource ( DataFlow2:: Node source ) {
154
- source .asExpr ( ) .getType ( ) .getName ( ) = "PageContext"
164
+ predicate isSink ( DataFlow:: Node sink ) { sink .asExpr ( ) instanceof Argument }
155
165
}
156
166
157
- override predicate isSink ( DataFlow2:: Node sink ) { sink .asExpr ( ) instanceof Argument }
167
+ module ContextFlow = TaintTracking:: Global< ContextFlowConfig > ;
168
+
169
+ import ContextFlow:: PathGraph
158
170
}
159
171
160
172
class RedirectToJsp extends ReturnStmt {
161
173
File jsp ;
162
174
163
175
RedirectToJsp ( ) {
164
- exists ( DataFlow2:: Node strLit , DataFlow2:: Node retVal , LiteralConfig lc |
165
- asLiteral ( strLit .asExpr ( ) ) .splitAt ( "/" ) + "_jsp.java" = jsp .getBaseName ( )
176
+ exists ( DataFlow2:: Node strLit , DataFlow2:: Node retVal |
177
+ strLit .asExpr ( ) . ( StringLiteral ) . getValue ( ) .splitAt ( "/" ) + "_jsp.java" = jsp .getBaseName ( )
166
178
|
167
- retVal .asExpr ( ) = this .getResult ( ) and lc . hasFlow ( strLit , retVal )
179
+ retVal .asExpr ( ) = this .getResult ( ) and LiteralConfig :: LiteralFlow :: flow ( strLit , retVal )
168
180
)
169
181
}
170
182
171
183
File getJspFile ( ) { result = jsp }
172
184
}
173
185
174
- from DataFlow:: PathNode source , DataFlow:: PathNode sink , XSSConfig conf , JSPExpr jspe
175
- where conf .hasFlowPath ( source , sink ) and jspe .isClosest ( sink .getNode ( ) .asExpr ( ) )
176
- select jspe , source , sink , "Cross-site scripting vulnerability due to $@." , source .getNode ( ) ,
177
- "user-provided value"
186
+ from Xss:: XssFlow:: PathNode source , Xss:: XssFlow:: PathNode sink , JSPTaintStep jspts
187
+ where
188
+ Xss:: XssFlow:: flowPath ( source , sink ) and
189
+ jspts .step ( source .getNode ( ) , sink .getNode ( ) )
190
+ select sink .getNode ( ) , source , sink , "Cross-site scripting vulnerability due to $@." ,
191
+ source .getNode ( ) , "user-provided value"
0 commit comments