Skip to content

Commit 2e8091f

Browse files
authored
Merge pull request #20419 from asgerf/js/express-json-send
JS: Model Express json and jsonp methods
2 parents 5ad332e + 0b90071 commit 2e8091f

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,40 @@ module Express {
781781
override RouteHandler getRouteHandler() { result = response.getRouteHandler() }
782782
}
783783

784+
/**
785+
* A call to `res.json()` or `res.jsonp()`.
786+
*
787+
* This sets the `content-type` header.
788+
*/
789+
private class ResponseJsonCall extends DataFlow::MethodCallNode, Http::HeaderDefinition {
790+
private ResponseSource response;
791+
792+
ResponseJsonCall() { this = response.ref().getAMethodCall(["json", "jsonp"]) }
793+
794+
override RouteHandler getRouteHandler() { result = response.getRouteHandler() }
795+
796+
override string getAHeaderName() { result = "content-type" }
797+
798+
override predicate defines(string headerName, string headerValue) {
799+
// Note: for `jsonp` the actual content-type header will be `text/javascript` or similar, but to avoid
800+
// generating a spurious HTML injection sink, we treat it as `application/json` here.
801+
headerName = "content-type" and headerValue = "application/json"
802+
}
803+
}
804+
805+
/**
806+
* An argument passed to the `json` or `jsonp` method of an HTTP response object.
807+
*/
808+
private class ResponseJsonCallArgument extends Http::ResponseSendArgument {
809+
ResponseJsonCall call;
810+
811+
ResponseJsonCallArgument() { this = call.getArgument(0) }
812+
813+
override RouteHandler getRouteHandler() { result = call.getRouteHandler() }
814+
815+
override HeaderDefinition getAnAssociatedHeaderDefinition() { result = call }
816+
}
817+
784818
/**
785819
* An invocation of the `cookie` method on an HTTP response object.
786820
*/
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const express = require('express');
2+
const app = express();
3+
4+
app.get('/test/json', function(req, res) {
5+
res.json(req.query.data);
6+
});
7+
8+
app.get('/test/jsonp', function(req, res) {
9+
res.jsonp(req.query.data);
10+
});

0 commit comments

Comments
 (0)