@@ -8,39 +8,47 @@ import semmle.code.java.dataflow.DataFlow
88import semmle.code.java.dataflow.TaintTracking
99private import semmle.code.java.StringFormat
1010
11- /**
12- * Holds if taint is propagated from `pred` to `succ`.
13- */
14- predicate requestForgeryStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
15- // propagate to a URI when its host is assigned to
16- exists ( UriCreation c | c .getHostArg ( ) = pred .asExpr ( ) | succ .asExpr ( ) = c )
17- or
18- // propagate to a URL when its host is assigned to
19- exists ( UrlConstructorCall c | c .getHostArg ( ) = pred .asExpr ( ) | succ .asExpr ( ) = c )
20- or
21- // propagate to a RequestEntity when its url is assigned to
22- exists ( MethodAccess m |
23- m .getMethod ( ) .getDeclaringType ( ) instanceof SpringRequestEntity and
24- (
25- m .getMethod ( ) .hasName ( [ "get" , "post" , "head" , "delete" , "options" , "patch" , "put" ] ) and
26- m .getArgument ( 0 ) = pred .asExpr ( ) and
27- m = succ .asExpr ( )
28- or
29- m .getMethod ( ) .hasName ( "method" ) and
30- m .getArgument ( 1 ) = pred .asExpr ( ) and
11+ abstract class RequestForgeryAdditionalTaintStep extends string {
12+ bindingset [ this ]
13+ RequestForgeryAdditionalTaintStep ( ) { any ( ) }
14+
15+ abstract predicate propagatesTaint ( DataFlow:: Node pred , DataFlow:: Node succ ) ;
16+ }
17+
18+ private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep {
19+ DefaultRequestForgeryAdditionalTaintStep ( ) { this = "DefaultRequestForgeryAdditionalTaintStep" }
20+
21+ override predicate propagatesTaint ( DataFlow:: Node pred , DataFlow:: Node succ ) {
22+ // propagate to a URI when its host is assigned to
23+ exists ( UriCreation c | c .getHostArg ( ) = pred .asExpr ( ) | succ .asExpr ( ) = c )
24+ or
25+ // propagate to a URL when its host is assigned to
26+ exists ( UrlConstructorCall c | c .getHostArg ( ) = pred .asExpr ( ) | succ .asExpr ( ) = c )
27+ or
28+ // propagate to a RequestEntity when its url is assigned to
29+ exists ( MethodAccess m |
30+ m .getMethod ( ) .getDeclaringType ( ) instanceof SpringRequestEntity and
31+ (
32+ m .getMethod ( ) .hasName ( [ "get" , "post" , "head" , "delete" , "options" , "patch" , "put" ] ) and
33+ m .getArgument ( 0 ) = pred .asExpr ( ) and
34+ m = succ .asExpr ( )
35+ or
36+ m .getMethod ( ) .hasName ( "method" ) and
37+ m .getArgument ( 1 ) = pred .asExpr ( ) and
38+ m = succ .asExpr ( )
39+ )
40+ )
41+ or
42+ // propagate from a `RequestEntity<>$BodyBuilder` to a `RequestEntity`
43+ // when the builder is tainted
44+ exists ( MethodAccess m , RefType t |
45+ m .getMethod ( ) .getDeclaringType ( ) = t and
46+ t .hasQualifiedName ( "org.springframework.http" , "RequestEntity<>$BodyBuilder" ) and
47+ m .getMethod ( ) .hasName ( "body" ) and
48+ m .getQualifier ( ) = pred .asExpr ( ) and
3149 m = succ .asExpr ( )
3250 )
33- )
34- or
35- // propagate from a `RequestEntity<>$BodyBuilder` to a `RequestEntity`
36- // when the builder is tainted
37- exists ( MethodAccess m , RefType t |
38- m .getMethod ( ) .getDeclaringType ( ) = t and
39- t .hasQualifiedName ( "org.springframework.http" , "RequestEntity<>$BodyBuilder" ) and
40- m .getMethod ( ) .hasName ( "body" ) and
41- m .getQualifier ( ) = pred .asExpr ( ) and
42- m = succ .asExpr ( )
43- )
51+ }
4452}
4553
4654/** A data flow sink for request forgery vulnerabilities. */
@@ -257,7 +265,7 @@ private MethodAccess getAChainedAppend(Expr e) {
257265 * a hostname or a URL separator, preventing the appended string from arbitrarily controlling
258266 * the addressed server.
259267 */
260- class HostnameSanitizedExpr extends Expr {
268+ private class HostnameSanitizedExpr extends Expr {
261269 HostnameSanitizedExpr ( ) {
262270 // Sanitize expressions that come after a sanitizing prefix in a tree of string additions:
263271 this = getASanitizedAddOperand ( )
@@ -311,6 +319,6 @@ class HostnameSanitizedExpr extends Expr {
311319 * A value that is the result of prepending a string that prevents any value from controlling the
312320 * host of a URL.
313321 */
314- class HostnameSantizer extends RequestForgerySanitizer {
322+ private class HostnameSantizer extends RequestForgerySanitizer {
315323 HostnameSantizer ( ) { this .asExpr ( ) instanceof HostnameSanitizedExpr }
316324}
0 commit comments