Skip to content

Commit da21a06

Browse files
committed
JS: add _parsedUrl as remote input source
1 parent 67aac7a commit da21a06

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

javascript/ql/lib/semmle/javascript/frameworks/Express.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ module Express {
620620
or
621621
// `req.path`
622622
kind = "url" and
623-
this = ref.getAPropertyRead("path")
623+
this = ref.getAPropertyRead(["path", "_parsedUrl"])
624624
)
625625
}
626626

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
| apollo.serverSide.ts:8:39:8:64 | get(fil ... => {}) | apollo.serverSide.ts:7:36:7:44 | { files } | apollo.serverSide.ts:8:43:8:50 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:8:43:8:50 | file.url | URL | apollo.serverSide.ts:7:36:7:44 | { files } | user-provided value |
77
| apollo.serverSide.ts:18:37:18:62 | get(fil ... => {}) | apollo.serverSide.ts:17:34:17:42 | { files } | apollo.serverSide.ts:18:41:18:48 | file.url | The $@ of this request depends on a $@. | apollo.serverSide.ts:18:41:18:48 | file.url | URL | apollo.serverSide.ts:17:34:17:42 | { files } | user-provided value |
88
| axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | The $@ of this request depends on a $@. | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | endpoint | axiosInterceptors.serverSide.js:19:21:19:28 | req.body | user-provided value |
9+
| serverSide2.js:20:29:20:49 | axios.g ... etUrl1) | serverSide2.js:9:43:9:56 | req._parsedUrl | serverSide2.js:20:39:20:48 | targetUrl1 | The $@ of this request depends on a $@. | serverSide2.js:20:39:20:48 | targetUrl1 | URL | serverSide2.js:9:43:9:56 | req._parsedUrl | user-provided value |
910
| serverSide2.js:23:29:23:49 | axios.g ... etUrl2) | serverSide2.js:22:24:22:30 | req.url | serverSide2.js:23:39:23:48 | targetUrl2 | The $@ of this request depends on a $@. | serverSide2.js:23:39:23:48 | targetUrl2 | URL | serverSide2.js:22:24:22:30 | req.url | user-provided value |
1011
| serverSide2.js:26:29:26:49 | axios.g ... etUrl3) | serverSide2.js:11:24:11:30 | req.url | serverSide2.js:26:39:26:48 | targetUrl3 | The $@ of this request depends on a $@. | serverSide2.js:26:39:26:48 | targetUrl3 | URL | serverSide2.js:11:24:11:30 | req.url | user-provided value |
1112
| serverSide.js:18:5:18:20 | request(tainted) | serverSide.js:14:29:14:35 | req.url | serverSide.js:18:13:18:19 | tainted | The $@ of this request depends on a $@. | serverSide.js:18:13:18:19 | tainted | URL | serverSide.js:14:29:14:35 | req.url | user-provided value |
@@ -63,7 +64,11 @@ edges
6364
| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | axiosInterceptors.serverSide.js:19:11:19:17 | { url } | provenance | |
6465
| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | axiosInterceptors.serverSide.js:11:26:11:40 | userProvidedUrl | provenance | |
6566
| axiosInterceptors.serverSide.js:20:23:20:25 | url | axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | provenance | |
67+
| serverSide2.js:9:34:9:63 | qs.pars ... .query) | serverSide2.js:19:24:19:51 | req.par ... rsedUrl | provenance | |
68+
| serverSide2.js:9:43:9:56 | req._parsedUrl | serverSide2.js:9:34:9:63 | qs.pars ... .query) | provenance | |
6669
| serverSide2.js:11:24:11:30 | req.url | serverSide2.js:25:24:25:41 | req.SomeObject.url | provenance | |
70+
| serverSide2.js:19:11:19:55 | targetUrl1 | serverSide2.js:20:39:20:48 | targetUrl1 | provenance | |
71+
| serverSide2.js:19:24:19:51 | req.par ... rsedUrl | serverSide2.js:19:11:19:55 | targetUrl1 | provenance | |
6772
| serverSide2.js:22:11:22:36 | targetUrl2 | serverSide2.js:23:39:23:48 | targetUrl2 | provenance | |
6873
| serverSide2.js:22:24:22:30 | req.url | serverSide2.js:22:11:22:36 | targetUrl2 | provenance | |
6974
| serverSide2.js:25:11:25:47 | targetUrl3 | serverSide2.js:26:39:26:48 | targetUrl3 | provenance | |
@@ -160,7 +165,12 @@ nodes
160165
| axiosInterceptors.serverSide.js:19:21:19:28 | req.body | semmle.label | req.body |
161166
| axiosInterceptors.serverSide.js:20:5:20:25 | userProvidedUrl | semmle.label | userProvidedUrl |
162167
| axiosInterceptors.serverSide.js:20:23:20:25 | url | semmle.label | url |
168+
| serverSide2.js:9:34:9:63 | qs.pars ... .query) | semmle.label | qs.pars ... .query) |
169+
| serverSide2.js:9:43:9:56 | req._parsedUrl | semmle.label | req._parsedUrl |
163170
| serverSide2.js:11:24:11:30 | req.url | semmle.label | req.url |
171+
| serverSide2.js:19:11:19:55 | targetUrl1 | semmle.label | targetUrl1 |
172+
| serverSide2.js:19:24:19:51 | req.par ... rsedUrl | semmle.label | req.par ... rsedUrl |
173+
| serverSide2.js:20:39:20:48 | targetUrl1 | semmle.label | targetUrl1 |
164174
| serverSide2.js:22:11:22:36 | targetUrl2 | semmle.label | targetUrl2 |
165175
| serverSide2.js:22:24:22:30 | req.url | semmle.label | req.url |
166176
| serverSide2.js:23:39:23:48 | targetUrl2 | semmle.label | targetUrl2 |

javascript/ql/test/query-tests/Security/CWE-918/serverSide2.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const app = express();
66
const PORT = 3000;
77

88
app.use((req, res, next) => {
9-
req.parsedQueryFromParsedUrl = qs.parse(req._parsedUrl.query); // $MISSING:Source[js/request-forgery]
9+
req.parsedQueryFromParsedUrl = qs.parse(req._parsedUrl.query); // $Source[js/request-forgery]
1010
req.parsedQuery.url = req.url || {}; // $MISSING:Source[js/request-forgery]
1111
req.SomeObject.url = req.url; // $Source[js/request-forgery]
1212
next();
@@ -17,7 +17,7 @@ app.get('/proxy', async (req, res) => {
1717
const response = await axios.get(targetUrl); // $MISSING:Alert[js/request-forgery]
1818

1919
const targetUrl1 = req.parsedQueryFromParsedUrl.url;
20-
const response1 = await axios.get(targetUrl1); // $MISSING:Alert[js/request-forgery]
20+
const response1 = await axios.get(targetUrl1); // $Alert[js/request-forgery]
2121

2222
const targetUrl2 = req.url || {}; // $Source[js/request-forgery]
2323
const response2 = await axios.get(targetUrl2); // $Alert[js/request-forgery]

0 commit comments

Comments
 (0)