Skip to content

Commit 18b06f1

Browse files
murderteethclaude
andcommitted
Model res.json and res.jsonp as Vercel response sinks
Vercel API handlers more often return JSON than HTML, so res.send is not the only response body sink that matters. Mirror Express's ResponseJsonCall by also matching res.json(...) and res.jsonp(...) on the response (direct and chained), and exercise the new behavior in the library-test fixture. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1b87140 commit 18b06f1

3 files changed

Lines changed: 27 additions & 18 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,16 @@ module VercelNode {
141141
}
142142

143143
/**
144-
* An argument to `res.send(...)` on a Vercel response, including chained
145-
* calls such as `res.status(200).send(...)`.
144+
* An argument to `res.send(...)`, `res.json(...)`, or `res.jsonp(...)` on a
145+
* Vercel response, including chained calls such as `res.status(200).json(...)`.
146146
*/
147147
private class ResponseSendArgument extends Http::ResponseSendArgument {
148148
RouteHandler rh;
149149

150150
ResponseSendArgument() {
151151
exists(Http::Servers::ResponseSource src |
152152
(src instanceof ResponseSource or src instanceof ChainedResponseSource) and
153-
this = src.ref().getAMethodCall("send").getArgument(0) and
153+
this = src.ref().getAMethodCall(["send", "json", "jsonp"]).getArgument(0) and
154154
rh = src.getRouteHandler()
155155
)
156156
}

javascript/ql/test/library-tests/frameworks/vercel/src/vercel.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export default function handler(req: VercelRequest, res: VercelResponse) {
2222
res.send(q);
2323
res.status(200).send(b);
2424

25+
// JSON response (direct and chained)
26+
res.json(c);
27+
res.status(200).json(u);
28+
res.jsonp(host);
29+
2530
// Redirect
2631
res.redirect(req.query.url as string);
2732
}
Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
test_RouteHandler
22
| src/now.ts:5:16:7:1 | functio ... ame);\\n} |
3-
| src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
3+
| src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
44
test_RequestSource
55
| src/now.ts:5:33:5:35 | req | src/now.ts:5:16:7:1 | functio ... ame);\\n} |
6-
| src/vercel.ts:9:33:9:35 | req | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
6+
| src/vercel.ts:9:33:9:35 | req | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
77
test_ResponseSource
88
| src/now.ts:5:50:5:52 | res | src/now.ts:5:16:7:1 | functio ... ame);\\n} |
9-
| src/vercel.ts:9:53:9:55 | res | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
10-
| src/vercel.ts:23:3:23:17 | res.status(200) | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
9+
| src/vercel.ts:9:53:9:55 | res | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
10+
| src/vercel.ts:23:3:23:17 | res.status(200) | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
11+
| src/vercel.ts:27:3:27:17 | res.status(200) | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
1112
test_HeaderDefinition
12-
| src/vercel.ts:19:3:19:44 | res.set ... /html") | content-type | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
13+
| src/vercel.ts:19:3:19:44 | res.set ... /html") | content-type | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
1314
test_RedirectInvocation
14-
| src/vercel.ts:26:3:26:39 | res.red ... string) | src/vercel.ts:26:16:26:38 | req.que ... string | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
15+
| src/vercel.ts:31:3:31:39 | res.red ... string) | src/vercel.ts:31:16:31:38 | req.que ... string | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
1516
test_RequestInputAccess
1617
| src/now.ts:6:12:6:20 | req.query | parameter | src/now.ts:5:16:7:1 | functio ... ame);\\n} |
17-
| src/vercel.ts:11:13:11:21 | req.query | parameter | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
18-
| src/vercel.ts:12:13:12:20 | req.body | body | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
19-
| src/vercel.ts:13:13:13:23 | req.cookies | cookie | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
20-
| src/vercel.ts:14:13:14:19 | req.url | url | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
21-
| src/vercel.ts:15:16:15:31 | req.headers.host | header | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
22-
| src/vercel.ts:16:15:16:33 | req.headers.referer | header | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
23-
| src/vercel.ts:26:16:26:24 | req.query | parameter | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
18+
| src/vercel.ts:11:13:11:21 | req.query | parameter | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
19+
| src/vercel.ts:12:13:12:20 | req.body | body | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
20+
| src/vercel.ts:13:13:13:23 | req.cookies | cookie | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
21+
| src/vercel.ts:14:13:14:19 | req.url | url | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
22+
| src/vercel.ts:15:16:15:31 | req.headers.host | header | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
23+
| src/vercel.ts:16:15:16:33 | req.headers.referer | header | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
24+
| src/vercel.ts:31:16:31:24 | req.query | parameter | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
2425
test_ResponseSendArgument
2526
| src/now.ts:6:12:6:25 | req.query.name | src/now.ts:5:16:7:1 | functio ... ame);\\n} |
26-
| src/vercel.ts:22:12:22:12 | q | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
27-
| src/vercel.ts:23:24:23:24 | b | src/vercel.ts:9:16:27:1 | functio ... ing);\\n} |
27+
| src/vercel.ts:22:12:22:12 | q | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
28+
| src/vercel.ts:23:24:23:24 | b | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
29+
| src/vercel.ts:26:12:26:12 | c | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
30+
| src/vercel.ts:27:24:27:24 | u | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |
31+
| src/vercel.ts:28:13:28:16 | host | src/vercel.ts:9:16:32:1 | functio ... ing);\\n} |

0 commit comments

Comments
 (0)