@@ -139,6 +139,79 @@ class LocalUrlSanitizer extends Sanitizer {
139139 LocalUrlSanitizer ( ) { this = DataFlow:: BarrierGuard< isLocalUrlSanitizer / 3 > :: getABarrierNode ( ) }
140140}
141141
142+ /**
143+ * An argument to a call to `List.Contains()` that is a sanitizer for URL redirects.
144+ */
145+ private predicate isContainsUrlSanitizer ( Guard guard , Expr e , AbstractValue v ) {
146+ guard =
147+ any ( MethodCall method |
148+ exists ( Method m | m = method .getTarget ( ) |
149+ m .hasName ( "Contains" ) and
150+ e = method .getArgument ( 0 )
151+ ) and
152+ v .( AbstractValues:: BooleanValue ) .getValue ( ) = true
153+ )
154+ }
155+
156+ /**
157+ * An URL argument to a call to `.Contains()` that is a sanitizer for URL redirects.
158+ *
159+ * This `Contains` method is usually called on a list, but the sanitizer matches any call to a method
160+ * called `Contains`, so other methods with the same name will also be considered sanitizers.
161+ */
162+ class ContainsUrlSanitizer extends Sanitizer {
163+ ContainsUrlSanitizer ( ) {
164+ this = DataFlow:: BarrierGuard< isContainsUrlSanitizer / 3 > :: getABarrierNode ( )
165+ }
166+ }
167+
168+ /**
169+ * A check that the URL is relative, and therefore safe for URL redirects.
170+ */
171+ private predicate isRelativeUrlSanitizer ( Guard guard , Expr e , AbstractValue v ) {
172+ guard =
173+ any ( PropertyAccess access |
174+ access .getProperty ( ) .hasFullyQualifiedName ( "System" , "Uri" , "IsAbsoluteUri" ) and
175+ e = access .getQualifier ( ) and
176+ v .( AbstractValues:: BooleanValue ) .getValue ( ) = false
177+ )
178+ }
179+
180+ /**
181+ * A check that the URL is relative, and therefore safe for URL redirects.
182+ */
183+ class RelativeUrlSanitizer extends Sanitizer {
184+ RelativeUrlSanitizer ( ) {
185+ this = DataFlow:: BarrierGuard< isRelativeUrlSanitizer / 3 > :: getABarrierNode ( )
186+ }
187+ }
188+
189+ /**
190+ * A comparison on the `Host` property of a url, that is a sanitizer for URL redirects.
191+ * E.g. `url.Host == "example.org"`
192+ */
193+ private predicate isHostComparisonSanitizer ( Guard guard , Expr e , AbstractValue v ) {
194+ guard =
195+ any ( EqualityOperation comparison |
196+ exists ( PropertyAccess access | access = comparison .getAnOperand ( ) |
197+ access .getProperty ( ) .hasFullyQualifiedName ( "System" , "Uri" , "Host" ) and
198+ e = access .getQualifier ( )
199+ ) and
200+ if comparison instanceof EQExpr
201+ then v .( AbstractValues:: BooleanValue ) .getValue ( ) = true
202+ else v .( AbstractValues:: BooleanValue ) .getValue ( ) = false
203+ )
204+ }
205+
206+ /**
207+ * A comparison on the `Host` property of a url, that is a sanitizer for URL redirects.
208+ */
209+ class HostComparisonSanitizer extends Sanitizer {
210+ HostComparisonSanitizer ( ) {
211+ this = DataFlow:: BarrierGuard< isHostComparisonSanitizer / 3 > :: getABarrierNode ( )
212+ }
213+ }
214+
142215/**
143216 * A call to the getter of the RawUrl property, whose value is considered to be safe for URL
144217 * redirects.
0 commit comments