@@ -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,76 @@ 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 a `.contains()` method that is a sanitizer for URL redirects.
90
+ *
91
+ * Matches any method call where the method is named `contains`.
92
+ */
93
+ private predicate isContainsUrlSanitizer ( Guard guard , Expr e , boolean branch ) {
94
+ guard =
95
+ any ( MethodCall method |
96
+ method .getMethod ( ) .getName ( ) = "contains" and
97
+ e = method .getArgument ( 0 ) and
98
+ branch = true
99
+ )
100
+ }
101
+
102
+ /**
103
+ * An URL argument to a call to `.contains()` that is a sanitizer for URL redirects.
104
+ *
105
+ * This `contains` method is usually called on a list, but the sanitizer matches any call to a method
106
+ * called `contains`, so other methods with the same name will also be considered sanitizers.
107
+ */
108
+ private class ContainsUrlSanitizer extends RequestForgerySanitizer {
109
+ ContainsUrlSanitizer ( ) {
110
+ this = DataFlow:: BarrierGuard< isContainsUrlSanitizer / 3 > :: getABarrierNode ( )
111
+ }
112
+ }
113
+
114
+ /**
115
+ * A check that the URL is relative, and therefore safe for URL redirects.
116
+ */
117
+ private predicate isRelativeUrlSanitizer ( Guard guard , Expr e , boolean branch ) {
118
+ guard =
119
+ any ( MethodCall call |
120
+ call .getMethod ( ) .hasQualifiedName ( "java.net" , "URI" , "isAbsolute" ) and
121
+ e = call .getQualifier ( ) and
122
+ branch = false
123
+ )
124
+ }
125
+
126
+ /**
127
+ * A check that the URL is relative, and therefore safe for URL redirects.
128
+ */
129
+ private class RelativeUrlSanitizer extends RequestForgerySanitizer {
130
+ RelativeUrlSanitizer ( ) {
131
+ this = DataFlow:: BarrierGuard< isRelativeUrlSanitizer / 3 > :: getABarrierNode ( )
132
+ }
133
+ }
134
+
135
+ /**
136
+ * A comparison on the host of a url, that is a sanitizer for URL redirects.
137
+ * E.g. `"example.org".equals(url.getHost())"`
138
+ */
139
+ private predicate isHostComparisonSanitizer ( Guard guard , Expr e , boolean branch ) {
140
+ guard =
141
+ any ( MethodCall equalsCall |
142
+ equalsCall .getMethod ( ) .getName ( ) = "equals" and
143
+ branch = true and
144
+ exists ( MethodCall hostCall |
145
+ hostCall = [ equalsCall .getQualifier ( ) , equalsCall .getArgument ( 0 ) ] and
146
+ hostCall .getMethod ( ) .hasQualifiedName ( "java.net" , "URI" , "getHost" ) and
147
+ e = hostCall .getQualifier ( )
148
+ )
149
+ )
150
+ }
151
+
152
+ /**
153
+ * A comparison on the `Host` property of a url, that is a sanitizer for URL redirects.
154
+ */
155
+ private class HostComparisonSanitizer extends RequestForgerySanitizer {
156
+ HostComparisonSanitizer ( ) {
157
+ this = DataFlow:: BarrierGuard< isHostComparisonSanitizer / 3 > :: getABarrierNode ( )
158
+ }
159
+ }
0 commit comments