66
77import javascript
88
9+ /**
10+ * Holds if the string value of `nd` prevents anything appended after it
11+ * from affecting the hostname or path of a URL.
12+ *
13+ * Specifically, this holds if the string contains `?` or `#`.
14+ */
15+ private predicate hasSanitizingSubstring ( DataFlow:: Node nd ) {
16+ nd .asExpr ( ) .getStringValue ( ) .regexpMatch ( ".*[?#].*" )
17+ or
18+ hasSanitizingSubstring ( StringConcatenation:: getAnOperand ( nd ) )
19+ or
20+ hasSanitizingSubstring ( nd .getAPredecessor ( ) )
21+ or
22+ nd .isIncomplete ( _)
23+ }
24+
25+ /**
26+ * Holds if data that flows from `source` to `sink` cannot affect the
27+ * path or earlier part of the resulting string when interpreted as a URL.
28+ *
29+ * This is considered as a sanitizing edge for the URL redirection queries.
30+ */
31+ predicate sanitizingPrefixEdge ( DataFlow:: Node source , DataFlow:: Node sink ) {
32+ exists ( DataFlow:: Node operator , int n |
33+ StringConcatenation:: taintStep ( source , sink , operator , n ) and
34+ hasSanitizingSubstring ( StringConcatenation:: getOperand ( operator , [ 0 ..n - 1 ] ) ) )
35+ }
36+
937/**
1038 * Holds if the string value of `nd` prevents anything appended after it
1139 * from affecting the hostname of a URL.
@@ -18,24 +46,24 @@ import javascript
1846 * In the latter case, the additional prefix check is necessary to avoid a `/` that could be interpreted as
1947 * the `//` separating the (optional) scheme from the hostname.
2048 */
21- predicate hasSanitizingSubstring ( DataFlow:: Node nd ) {
49+ private predicate hasHostnameSanitizingSubstring ( DataFlow:: Node nd ) {
2250 nd .asExpr ( ) .getStringValue ( ) .regexpMatch ( ".*([?#]|[^?#:/\\\\][/\\\\]).*" )
2351 or
24- hasSanitizingSubstring ( StringConcatenation:: getAnOperand ( nd ) )
52+ hasHostnameSanitizingSubstring ( StringConcatenation:: getAnOperand ( nd ) )
2553 or
26- hasSanitizingSubstring ( nd .getAPredecessor ( ) )
54+ hasHostnameSanitizingSubstring ( nd .getAPredecessor ( ) )
2755 or
2856 nd .isIncomplete ( _)
2957}
3058
3159/**
3260 * Holds if data that flows from `source` to `sink` cannot affect the
33- * hostname of the resulting string when interpreted as a URL.
61+ * hostname or scheme of the resulting string when interpreted as a URL.
3462 *
3563 * This is considered as a sanitizing edge for the URL redirection queries.
3664 */
37- predicate sanitizingPrefixEdge ( DataFlow:: Node source , DataFlow:: Node sink ) {
65+ predicate hostnameSanitizingPrefixEdge ( DataFlow:: Node source , DataFlow:: Node sink ) {
3866 exists ( DataFlow:: Node operator , int n |
3967 StringConcatenation:: taintStep ( source , sink , operator , n ) and
4068 hasSanitizingSubstring ( StringConcatenation:: getOperand ( operator , [ 0 ..n - 1 ] ) ) )
41- }
69+ }
0 commit comments