diff --git a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp
index 71fefb488fa3..b770c061a5c2 100644
--- a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp
+++ b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp
@@ -59,14 +59,14 @@
Address this vulnerability by escaping .
- appropriately: let regex = /(www|beta|)\.example\.com/.
+ appropriately: let regex = /((www|beta)\.)?example\.com/.
- OWASP: SSRF
+ MDN: Regular Expressions OWASP: SSRF
OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
diff --git a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.ql b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.ql
index 049b7f4c64a7..3ee80ef88cc3 100644
--- a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.ql
+++ b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.ql
@@ -11,18 +11,27 @@
*/
import javascript
+import SmallStrings
/**
* A taint tracking configuration for incomplete hostname regular expressions sources.
*/
-class Configuration extends TaintTracking::Configuration {
+class Configuration extends DataFlow::Configuration {
Configuration() { this = "IncompleteHostnameRegExpTracking" }
override predicate isSource(DataFlow::Node source) {
- isIncompleteHostNameRegExpPattern(source.getStringValue(), _)
+ exists (string pattern |
+ isSmallRegExpPattern(source, pattern) and
+ isIncompleteHostNameRegExpPattern(pattern, _)
+ )
}
override predicate isSink(DataFlow::Node sink) { isInterpretedAsRegExp(sink) }
+
+ override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
+ any(TaintTracking::AdditionalTaintStep dts).step(pred, succ)
+ }
+
}
/**
@@ -36,22 +45,23 @@ predicate isIncompleteHostNameRegExpPattern(string pattern, string hostPart) {
// an unescaped single `.`
"(?>
- result = "com|org|edu|gov|uk|net|io"
+ result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])"
}
}
diff --git a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected
index cbb655c77bab..40a5f2852575 100644
--- a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteHostnameRegExp.expected
@@ -2,20 +2,20 @@
| tst-IncompleteHostnameRegExp.js:5:2:5:28 | /http:\\ ... le.net/ | This regular expression has an unescaped '.' before 'example.net', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:6:2:6:42 | /http:\\ ... b).com/ | This regular expression has an unescaped '.' before '(example-a\|example-b).com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:11:13:11:37 | "http:/ ... le.com" | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
-| tst-IncompleteHostnameRegExp.js:12:10:12:34 | "http:/ ... le.com" | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
+| tst-IncompleteHostnameRegExp.js:12:10:12:35 | "^http: ... le.com" | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:15:22:15:46 | "http:/ ... le.com" | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:17:13:17:31 | `test.example.com$` | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
-| tst-IncompleteHostnameRegExp.js:17:14:17:30 | test.example.com$ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:19:17:19:34 | 'test.example.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:22:27:22:44 | 'test.example.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:28:22:28:39 | 'test.example.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
+| tst-IncompleteHostnameRegExp.js:30:30:30:47 | 'test.example.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:37:2:37:54 | /^(http ... =$\|\\/)/ | This regular expression has an unescaped '.' before ')?example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:38:2:38:44 | /^(http ... p\\/f\\// | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:39:2:39:34 | /\\(http ... m\\/\\)/g | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:40:2:40:29 | /https? ... le.com/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
-| tst-IncompleteHostnameRegExp.js:41:13:41:68 | '^http: ... e\\.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:41:41:41:68 | '^https ... e\\.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:42:13:42:61 | 'http[s ... \\/(.+)' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:43:2:43:33 | /^https ... e.com$/ | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:44:9:44:100 | 'protos ... ernal)' | This regular expression has an unescaped '.' before 'example-b.com', so it might match more hosts than expected. |
| tst-IncompleteHostnameRegExp.js:46:2:46:26 | /exampl ... le.com/ | This regular expression has an unescaped '.' before 'dev\|example.com', so it might match more hosts than expected. |
+| tst-IncompleteHostnameRegExp.js:48:41:48:68 | '^https ... e\\.com' | This regular expression has an unescaped '.' before 'example.com', so it might match more hosts than expected. |
diff --git a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteUrlSubstringSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteUrlSubstringSanitization.expected
index efbaad5a6729..7474fced479c 100644
--- a/javascript/ql/test/query-tests/Security/CWE-020/IncompleteUrlSubstringSanitization.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-020/IncompleteUrlSubstringSanitization.expected
@@ -1,22 +1,67 @@
-| tst-IncompleteUrlSubstringSanitization.js:4:5:4:34 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:5:5:5:34 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | secure.net |
-| tst-IncompleteUrlSubstringSanitization.js:6:5:6:35 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | .secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:10:5:10:34 | x.index ... === -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:11:5:11:33 | x.index ... ) === 0 | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:12:5:12:32 | x.index ... ") >= 0 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:14:5:14:38 | x.start ... e.com") | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | https://secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:15:5:15:28 | x.endsW ... e.com") | '$@' may be preceded by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:20:5:20:28 | x.inclu ... e.com") | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:32:5:32:42 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | https://secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:33:5:33:46 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | https://secure.com:443 |
-| tst-IncompleteUrlSubstringSanitization.js:34:5:34:43 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | https://secure.com/ |
-| tst-IncompleteUrlSubstringSanitization.js:52:5:52:48 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | https://example.internal |
-| tst-IncompleteUrlSubstringSanitization.js:55:5:55:44 | x.start ... ernal") | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" | https://example.internal |
-| tst-IncompleteUrlSubstringSanitization.js:56:5:56:51 | x.index ... ) !== 0 | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' | https://example.internal.org |
-| tst-IncompleteUrlSubstringSanitization.js:57:5:57:51 | x.index ... ) === 0 | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' | https://example.internal.org |
-| tst-IncompleteUrlSubstringSanitization.js:58:5:58:30 | x.endsW ... l.com") | '$@' may be preceded by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" | internal.com |
-| tst-IncompleteUrlSubstringSanitization.js:61:2:61:31 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:62:2:62:31 | x.index ... === -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:63:4:63:33 | x.index ... !== -1 | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:64:3:64:26 | x.inclu ... e.com") | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | secure.com |
-| tst-IncompleteUrlSubstringSanitization.js:66:6:66:29 | x.inclu ... e.com") | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | secure.com |
+nodes
+| tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" |
+| tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:16:16:16:28 | ".secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:17:18:17:30 | "secure.com/" |
+| tst-IncompleteUrlSubstringSanitization.js:18:15:18:27 | "secure.com/" |
+| tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" |
+| tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" |
+| tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" |
+| tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" |
+| tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' |
+| tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' |
+| tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" |
+| tst-IncompleteUrlSubstringSanitization.js:59:18:59:46 | "https: ... nal:80" |
+| tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" |
+| tst-IncompleteUrlSubstringSanitization.js:72:6:75:2 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:72:23:75:2 | [\\n\\t\\t"se ... com"\\n\\t] |
+| tst-IncompleteUrlSubstringSanitization.js:73:3:73:15 | "secure1.com" |
+| tst-IncompleteUrlSubstringSanitization.js:74:3:74:16 | ".secure2.com" |
+| tst-IncompleteUrlSubstringSanitization.js:77:12:77:24 | trustedDomain |
+| tst-IncompleteUrlSubstringSanitization.js:77:29:77:42 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:78:24:78:36 | trustedDomain |
+edges
+| tst-IncompleteUrlSubstringSanitization.js:72:6:75:2 | trustedDomains | tst-IncompleteUrlSubstringSanitization.js:76:2:76:1 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:72:6:75:2 | trustedDomains | tst-IncompleteUrlSubstringSanitization.js:77:29:77:42 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:72:23:75:2 | [\\n\\t\\t"se ... com"\\n\\t] | tst-IncompleteUrlSubstringSanitization.js:72:6:75:2 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:73:3:73:15 | "secure1.com" | tst-IncompleteUrlSubstringSanitization.js:72:23:75:2 | [\\n\\t\\t"se ... com"\\n\\t] |
+| tst-IncompleteUrlSubstringSanitization.js:74:3:74:16 | ".secure2.com" | tst-IncompleteUrlSubstringSanitization.js:72:23:75:2 | [\\n\\t\\t"se ... com"\\n\\t] |
+| tst-IncompleteUrlSubstringSanitization.js:76:2:76:1 | trustedDomains | tst-IncompleteUrlSubstringSanitization.js:77:29:77:42 | trustedDomains |
+| tst-IncompleteUrlSubstringSanitization.js:77:12:77:24 | trustedDomain | tst-IncompleteUrlSubstringSanitization.js:78:24:78:36 | trustedDomain |
+| tst-IncompleteUrlSubstringSanitization.js:77:29:77:42 | trustedDomains | tst-IncompleteUrlSubstringSanitization.js:77:12:77:24 | trustedDomain |
+#select
+| tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | secure.net |
+| tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | .secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | https://secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | '$@' may be preceded by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | https://secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | https://secure.com:443 |
+| tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | https://secure.com/ |
+| tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | https://example.internal |
+| tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" | tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" | tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:55:18:55:43 | "https: ... ternal" | https://example.internal |
+| tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' | tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' | tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:56:15:56:44 | 'https: ... al.org' | https://example.internal.org |
+| tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' | tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' | tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' | '$@' may be followed by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:57:15:57:44 | 'https: ... al.org' | https://example.internal.org |
+| tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" | tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" | tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" | '$@' may be preceded by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:58:16:58:29 | "internal.com" | internal.com |
+| tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:61:12:61:23 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:62:12:62:23 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:63:14:63:25 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:64:14:64:25 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | '$@' can be anywhere in the URL, and arbitrary hosts may come before or after it. | tst-IncompleteUrlSubstringSanitization.js:66:17:66:28 | "secure.com" | secure.com |
+| tst-IncompleteUrlSubstringSanitization.js:78:24:78:36 | trustedDomain | tst-IncompleteUrlSubstringSanitization.js:73:3:73:15 | "secure1.com" | tst-IncompleteUrlSubstringSanitization.js:78:24:78:36 | trustedDomain | '$@' may be preceded by an arbitrary host name. | tst-IncompleteUrlSubstringSanitization.js:73:3:73:15 | "secure1.com" | secure1.com |
diff --git a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js
index 45e6476a22e1..8407cece53c2 100644
--- a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js
+++ b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteHostnameRegExp.js
@@ -9,7 +9,7 @@
/http:\/\/(?:.+)\\.test\\.example.com/; // NOT OK, but not yet supported with enough precision
/http:\/\/test.example.com\/(?:.*)/; // OK
new RegExp("http://test.example.com"); // NOT OK
- s.match("http://test.example.com"); // NOT OK
+ s.match("^http://test.example.com"); // NOT OK
function id(e) { return e; }
new RegExp(id(id(id("http://test.example.com")))); // NOT OK
@@ -27,7 +27,7 @@
}
convert({ hostname: 'test.example.com' }); // NOT OK
- let domains = [ { hostname: 'test.example.com' } ]; // NOT OK, but not yet supported
+ let domains = [ { hostname: 'test.example.com' } ]; // NOT OK
function convert(domain) {
return new RegExp(domain.hostname);
}
@@ -44,4 +44,7 @@
RegExp('protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)'); // NOT OK
/example.dev|example.com/; // OK, but still flagged
+
+ new RegExp('^http://localhost:8000|' + '^https?://.+\.example\.com'); // NOT OK
+
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteUrlSubstringSanitization.js b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteUrlSubstringSanitization.js
index f7246c2a401b..a26729c32aa4 100644
--- a/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteUrlSubstringSanitization.js
+++ b/javascript/ql/test/query-tests/Security/CWE-020/tst-IncompleteUrlSubstringSanitization.js
@@ -68,4 +68,21 @@
} else {
doSomeThingWithTrustedURL(x);
}
+
+ let trustedDomains = [
+ "secure1.com", // NOT OK, referenced below
+ ".secure2.com"
+ ];
+ function isTrustedDomain(domain) {
+ for (let trustedDomain of trustedDomains) {
+ if (domain.endsWith(trustedDomain)) return true; // NOT OK
+ }
+ return false;
+ }
+
+ let trustedHosts = [
+ "secure1.com"
+ ];
+ trustedHosts.includes(host); // OK: `Array.prototype.includes`
+
});