Skip to content

Commit e1838d4

Browse files
committed
JS: use original sanitizer for SSRF query
1 parent ade8a61 commit e1838d4

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/ClientSideUrlRedirect.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ module ClientSideUrlRedirect {
5858
}
5959

6060
override predicate isSanitizer(DataFlow::Node source, DataFlow::Node sink) {
61-
sanitizingPrefixEdge(source, sink)
61+
hostnameSanitizingPrefixEdge(source, sink)
6262
}
6363

6464
override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ, DataFlow::FlowLabel f, DataFlow::FlowLabel g) {

javascript/ql/src/semmle/javascript/security/dataflow/ServerSideUrlRedirect.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module ServerSideUrlRedirect {
4343
}
4444

4545
override predicate isSanitizer(DataFlow::Node source, DataFlow::Node sink) {
46-
sanitizingPrefixEdge(source, sink)
46+
hostnameSanitizingPrefixEdge(source, sink)
4747
}
4848

4949
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {

javascript/ql/src/semmle/javascript/security/dataflow/UrlConcatenation.qll

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@
66

77
import 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+
}

javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33
| tst.js:22:5:22:20 | request(options) | The $@ of this request depends on $@. | tst.js:21:19:21:25 | tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
44
| tst.js:24:5:24:32 | request ... ainted) | The $@ of this request depends on $@. | tst.js:24:13:24:31 | "http://" + tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
55
| tst.js:26:5:26:43 | request ... ainted) | The $@ of this request depends on $@. | tst.js:26:13:26:42 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |
6-
| tst.js:28:5:28:44 | request ... ainted) | The $@ of this request depends on $@. | tst.js:28:13:28:43 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value |

0 commit comments

Comments
 (0)