Skip to content

Commit 9384b85

Browse files
committed
JavaScript: ensure prefix sanitizers work for array.join()
1 parent e2cdf5d commit 9384b85

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

javascript/ql/src/semmle/javascript/StringConcatenation.qll

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,19 @@ module StringConcatenation {
2828
or
2929
n = 1 and result = assign.getRhs().flow())
3030
or
31-
exists (DataFlow::ArrayCreationNode array |
32-
node = array.getAMethodCall("join") and
33-
node.(DataFlow::MethodCallNode).getArgument(0).mayHaveStringValue("") and
34-
result = array.getElement(n))
31+
exists (DataFlow::ArrayCreationNode array, DataFlow::MethodCallNode call |
32+
call = array.getAMethodCall("join") and
33+
call.getArgument(0).mayHaveStringValue("") and
34+
(
35+
// step from array element to array
36+
result = array.getElement(n) and
37+
node = array
38+
or
39+
// step from array to join call
40+
node = call and
41+
result = array and
42+
n = 0
43+
))
3544
}
3645

3746
/** Gets an operand to the string concatenation defining `node`. */

javascript/ql/test/library-tests/StringConcatenation/ContainsTwo.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@
1414
| tst.js:20:3:20:25 | x += (" ... "four") |
1515
| tst.js:21:10:21:10 | x |
1616
| tst.js:21:10:21:19 | x + "five" |
17+
| tst.js:25:10:25:32 | ["one", ... three"] |
1718
| tst.js:25:10:25:41 | ["one", ... oin("") |
1819
| tst.js:25:18:25:22 | "two" |
20+
| tst.js:29:10:29:37 | Array(" ... three") |
1921
| tst.js:29:10:29:46 | Array(" ... oin("") |
2022
| tst.js:29:23:29:27 | "two" |
23+
| tst.js:33:10:33:41 | new Arr ... three") |
2124
| tst.js:33:10:33:50 | new Arr ... oin("") |
2225
| tst.js:33:27:33:31 | "two" |
2326
| tst.js:38:11:38:15 | "two" |

javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
| express.js:78:16:78:43 | `${req. ... )}/foo` | Untrusted URL redirection due to $@. | express.js:78:19:78:37 | req.param("target") | user-provided value |
77
| express.js:94:18:94:23 | target | Untrusted URL redirection due to $@. | express.js:87:16:87:34 | req.param("target") | user-provided value |
88
| express.js:101:16:101:21 | target | Untrusted URL redirection due to $@. | express.js:87:16:87:34 | req.param("target") | user-provided value |
9+
| express.js:119:16:119:72 | [req.qu ... oin('') | Untrusted URL redirection due to $@. | express.js:119:17:119:30 | req.query.page | user-provided value |
910
| node.js:7:34:7:39 | target | Untrusted URL redirection due to $@. | node.js:6:26:6:32 | req.url | user-provided value |
1011
| node.js:15:34:15:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:11:26:11:32 | req.url | user-provided value |
1112
| node.js:32:34:32:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:29:26:29:32 | req.url | user-provided value |

javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/express.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,14 @@ app.get('/some/path', function(req, res) {
110110
else
111111
res.redirect(target);
112112
});
113+
114+
app.get('/array/join', function(req, res) {
115+
// GOOD: request input embedded in query string
116+
res.redirect(['index.html?section=', req.query.section].join(''));
117+
118+
// GOOD: request input still embedded in query string
119+
res.redirect(['index.html?section=', '34'].join('') + '&subsection=' + req.query.subsection);
120+
121+
// BAD: request input becomes before query string
122+
res.redirect([req.query.page, '?section=', req.query.section].join(''));
123+
});

0 commit comments

Comments
 (0)