@@ -8,6 +8,7 @@ import semmle.code.java.frameworks.JaxWS
8
8
import semmle.code.java.frameworks.javase.Http
9
9
import semmle.code.java.dataflow.DataFlow
10
10
import semmle.code.java.frameworks.Properties
11
+ private import semmle.code.java.controlflow.Guards
11
12
private import semmle.code.java.dataflow.StringPrefixes
12
13
private import semmle.code.java.dataflow.ExternalFlow
13
14
private import semmle.code.java.security.Sanitizers
@@ -83,3 +84,79 @@ private class HostnameSanitizingPrefix extends InterestingPrefix {
83
84
private class HostnameSantizer extends RequestForgerySanitizer {
84
85
HostnameSantizer ( ) { this .asExpr ( ) = any ( HostnameSanitizingPrefix hsp ) .getAnAppendedExpression ( ) }
85
86
}
87
+
88
+ /**
89
+ * An argument to a call to `List.contains()` that is a sanitizer for URL redirects.
90
+ */
91
+ private predicate isContainsUrlSanitizer ( Guard guard , Expr e , boolean branch ) {
92
+ guard =
93
+ any ( MethodCall method |
94
+ method .getMethod ( ) .getName ( ) = "contains" and
95
+ e = method .getArgument ( 0 ) and
96
+ branch = true
97
+ )
98
+ }
99
+
100
+ /**
101
+ * An URL argument to a call to `.contains()` that is a sanitizer for URL redirects.
102
+ *
103
+ * This `contains` method is usually called on a list, but the sanitizer matches any call to a method
104
+ * called `contains`, so other methods with the same name will also be considered sanitizers.
105
+ */
106
+ class ContainsUrlSanitizer extends RequestForgerySanitizer {
107
+ ContainsUrlSanitizer ( ) {
108
+ this = DataFlow:: BarrierGuard< isContainsUrlSanitizer / 3 > :: getABarrierNode ( )
109
+ }
110
+ }
111
+
112
+ /**
113
+ * A check that the URL is relative, and therefore safe for URL redirects.
114
+ */
115
+ private predicate isRelativeUrlSanitizer ( Guard guard , Expr e , boolean branch ) {
116
+ guard =
117
+ any ( MethodCall call |
118
+ exists ( Method method |
119
+ call .getMethod ( ) = method and
120
+ method .getName ( ) = "isAbsolute" and
121
+ method .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URI" )
122
+ ) and
123
+ e = call .getQualifier ( ) and
124
+ branch = false
125
+ )
126
+ }
127
+
128
+ /**
129
+ * A check that the URL is relative, and therefore safe for URL redirects.
130
+ */
131
+ class RelativeUrlSanitizer extends RequestForgerySanitizer {
132
+ RelativeUrlSanitizer ( ) {
133
+ this = DataFlow:: BarrierGuard< isRelativeUrlSanitizer / 3 > :: getABarrierNode ( )
134
+ }
135
+ }
136
+
137
+ /**
138
+ * A comparison on the host of a url, that is a sanitizer for URL redirects.
139
+ * E.g. `"example.org".equals(url.getHost())"`
140
+ */
141
+ private predicate isHostComparisonSanitizer ( Guard guard , Expr e , boolean branch ) {
142
+ guard =
143
+ any ( MethodCall equalsCall |
144
+ equalsCall .getMethod ( ) .getName ( ) = "equals" and
145
+ branch = true and
146
+ exists ( MethodCall hostCall |
147
+ hostCall = [ equalsCall .getQualifier ( ) , equalsCall .getArgument ( 0 ) ] and
148
+ hostCall .getMethod ( ) .getName ( ) = "getHost" and
149
+ hostCall .getMethod ( ) .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URI" ) and
150
+ e = hostCall .getQualifier ( )
151
+ )
152
+ )
153
+ }
154
+
155
+ /**
156
+ * A comparison on the `Host` property of a url, that is a sanitizer for URL redirects.
157
+ */
158
+ class HostComparisonSanitizer extends RequestForgerySanitizer {
159
+ HostComparisonSanitizer ( ) {
160
+ this = DataFlow:: BarrierGuard< isHostComparisonSanitizer / 3 > :: getABarrierNode ( )
161
+ }
162
+ }
0 commit comments