Skip to content

Commit 86b64af

Browse files
committed
Added NextResponse to the ResponseCall class it models similar near idential behaviour.
1 parent 8acb024 commit 86b64af

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ private class HeadersEntryPoint extends API::EntryPoint {
1919
}
2020

2121
/**
22-
* A call to the `Response` constructor.
22+
* A call to the `Response` and `NextResponse` constructor.
2323
*/
2424
private class ResponseCall extends API::InvokeNode {
25-
ResponseCall() { this = any(ResponseEntryPoint e).getANode().getAnInstantiation() }
25+
ResponseCall() {
26+
this = any(ResponseEntryPoint e).getANode().getAnInstantiation() or
27+
this = API::moduleImport("next/server").getMember("NextResponse").getAnInstantiation()
28+
}
2629
}
2730

2831
/**

javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
| app/api/route.ts:13:18:13:21 | body | app/api/route.ts:2:24:2:33 | req.json() | app/api/route.ts:13:18:13:21 | body | Cross-site scripting vulnerability due to a $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
3232
| app/api/route.ts:25:18:25:21 | body | app/api/route.ts:2:24:2:33 | req.json() | app/api/route.ts:25:18:25:21 | body | Cross-site scripting vulnerability due to a $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
3333
| app/api/route.ts:29:25:29:28 | body | app/api/route.ts:2:24:2:33 | req.json() | app/api/route.ts:29:25:29:28 | body | Cross-site scripting vulnerability due to a $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
34+
| app/api/routeNextRequest.ts:7:20:7:23 | body | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | app/api/routeNextRequest.ts:7:20:7:23 | body | Cross-site scripting vulnerability due to a $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
35+
| app/api/routeNextRequest.ts:15:20:15:23 | body | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | app/api/routeNextRequest.ts:15:20:15:23 | body | Cross-site scripting vulnerability due to a $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
36+
| app/api/routeNextRequest.ts:27:20:27:23 | body | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | app/api/routeNextRequest.ts:27:20:27:23 | body | Cross-site scripting vulnerability due to a $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
37+
| app/api/routeNextRequest.ts:31:27:31:30 | body | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | app/api/routeNextRequest.ts:31:27:31:30 | body | Cross-site scripting vulnerability due to a $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
3438
| etherpad.js:11:12:11:19 | response | etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:11:12:11:19 | response | Cross-site scripting vulnerability due to a $@. | etherpad.js:9:16:9:30 | req.query.jsonp | user-provided value |
3539
| formatting.js:6:14:6:47 | util.fo ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:6:14:6:47 | util.fo ... , evil) | Cross-site scripting vulnerability due to a $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
3640
| formatting.js:7:14:7:53 | require ... , evil) | formatting.js:4:16:4:29 | req.query.evil | formatting.js:7:14:7:53 | require ... , evil) | Cross-site scripting vulnerability due to a $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
@@ -138,6 +142,12 @@ edges
138142
| app/api/route.ts:2:11:2:33 | body | app/api/route.ts:29:25:29:28 | body | provenance | |
139143
| app/api/route.ts:2:18:2:33 | await req.json() | app/api/route.ts:2:11:2:33 | body | provenance | |
140144
| app/api/route.ts:2:24:2:33 | req.json() | app/api/route.ts:2:18:2:33 | await req.json() | provenance | |
145+
| app/api/routeNextRequest.ts:4:9:4:31 | body | app/api/routeNextRequest.ts:7:20:7:23 | body | provenance | |
146+
| app/api/routeNextRequest.ts:4:9:4:31 | body | app/api/routeNextRequest.ts:15:20:15:23 | body | provenance | |
147+
| app/api/routeNextRequest.ts:4:9:4:31 | body | app/api/routeNextRequest.ts:27:20:27:23 | body | provenance | |
148+
| app/api/routeNextRequest.ts:4:9:4:31 | body | app/api/routeNextRequest.ts:31:27:31:30 | body | provenance | |
149+
| app/api/routeNextRequest.ts:4:16:4:31 | await req.json() | app/api/routeNextRequest.ts:4:9:4:31 | body | provenance | |
150+
| app/api/routeNextRequest.ts:4:22:4:31 | req.json() | app/api/routeNextRequest.ts:4:16:4:31 | await req.json() | provenance | |
141151
| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | provenance | |
142152
| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:5:9:53 | response | provenance | |
143153
| formatting.js:4:9:4:29 | evil | formatting.js:6:43:6:46 | evil | provenance | |
@@ -326,6 +336,13 @@ nodes
326336
| app/api/route.ts:13:18:13:21 | body | semmle.label | body |
327337
| app/api/route.ts:25:18:25:21 | body | semmle.label | body |
328338
| app/api/route.ts:29:25:29:28 | body | semmle.label | body |
339+
| app/api/routeNextRequest.ts:4:9:4:31 | body | semmle.label | body |
340+
| app/api/routeNextRequest.ts:4:16:4:31 | await req.json() | semmle.label | await req.json() |
341+
| app/api/routeNextRequest.ts:4:22:4:31 | req.json() | semmle.label | req.json() |
342+
| app/api/routeNextRequest.ts:7:20:7:23 | body | semmle.label | body |
343+
| app/api/routeNextRequest.ts:15:20:15:23 | body | semmle.label | body |
344+
| app/api/routeNextRequest.ts:27:20:27:23 | body | semmle.label | body |
345+
| app/api/routeNextRequest.ts:31:27:31:30 | body | semmle.label | body |
329346
| etherpad.js:9:5:9:53 | response | semmle.label | response |
330347
| etherpad.js:9:16:9:30 | req.query.jsonp | semmle.label | req.query.jsonp |
331348
| etherpad.js:11:12:11:19 | response | semmle.label | response |

javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
| app/api/route.ts:13:18:13:21 | body | Cross-site scripting vulnerability due to $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
3131
| app/api/route.ts:25:18:25:21 | body | Cross-site scripting vulnerability due to $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
3232
| app/api/route.ts:29:25:29:28 | body | Cross-site scripting vulnerability due to $@. | app/api/route.ts:2:24:2:33 | req.json() | user-provided value |
33+
| app/api/routeNextRequest.ts:7:20:7:23 | body | Cross-site scripting vulnerability due to $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
34+
| app/api/routeNextRequest.ts:15:20:15:23 | body | Cross-site scripting vulnerability due to $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
35+
| app/api/routeNextRequest.ts:27:20:27:23 | body | Cross-site scripting vulnerability due to $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
36+
| app/api/routeNextRequest.ts:31:27:31:30 | body | Cross-site scripting vulnerability due to $@. | app/api/routeNextRequest.ts:4:22:4:31 | req.json() | user-provided value |
3337
| formatting.js:6:14:6:47 | util.fo ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
3438
| formatting.js:7:14:7:53 | require ... , evil) | Cross-site scripting vulnerability due to $@. | formatting.js:4:16:4:29 | req.query.evil | user-provided value |
3539
| live-server.js:6:13:6:50 | `<html> ... /html>` | Cross-site scripting vulnerability due to $@. | live-server.js:4:21:4:27 | req.url | user-provided value |
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { NextRequest, NextResponse } from 'next/server';
22

33
export async function POST(req: NextRequest) {
4-
const body = await req.json(); // $ MISSING: Source
4+
const body = await req.json(); // $ Source
55

66
new NextResponse(body, {headers: { 'Content-Type': 'application/json' }});
7-
new NextResponse(body, {headers: { 'Content-Type': 'text/html' }}); // $ MISSING: Alert
7+
new NextResponse(body, {headers: { 'Content-Type': 'text/html' }}); // $ Alert
88

99
const headers2 = new Headers(req.headers);
1010
headers2.append('Content-Type', 'application/json');
1111
new NextResponse(body, { headers: headers2 });
1212

1313
const headers3 = new Headers(req.headers);
1414
headers3.append('Content-Type', 'text/html');
15-
new NextResponse(body, { headers: headers3 }); // $ MISSING: Alert
15+
new NextResponse(body, { headers: headers3 }); // $ Alert
1616

1717
const headers4 = new Headers({
1818
...Object.fromEntries(req.headers),
@@ -24,9 +24,9 @@ export async function POST(req: NextRequest) {
2424
...Object.fromEntries(req.headers),
2525
'Content-Type': 'text/html'
2626
});
27-
new NextResponse(body, { headers: headers5 }); // $ MISSING: Alert
27+
new NextResponse(body, { headers: headers5 }); // $ Alert
2828

2929
const headers = new Headers(req.headers);
3030
headers.set('Content-Type', 'text/html');
31-
return new NextResponse(body, { headers }); // $ MISSING: Alert
31+
return new NextResponse(body, { headers }); // $ Alert
3232
}

0 commit comments

Comments
 (0)