diff --git a/change-notes/1.24/analysis-javascript.md b/change-notes/1.24/analysis-javascript.md index 4563909f0c4..be904652139 100644 --- a/change-notes/1.24/analysis-javascript.md +++ b/change-notes/1.24/analysis-javascript.md @@ -26,6 +26,7 @@ - [for-own](https://www.npmjs.com/package/for-own) - [send](https://www.npmjs.com/package/send) - [chrome-remote-interface](https://www.npmjs.com/package/chrome-remote-interface) + - [http2](https://nodejs.org/api/http2.html) ## New queries diff --git a/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll b/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll index 5674c55ec3e..45fd12054b6 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll @@ -119,8 +119,11 @@ module HTTP { } /** + * DEPRECATED: Use `http` or `https` directly as appropriate. + * * Gets the string `http` or `https`. */ + deprecated string httpOrHttps() { result = "http" or result = "https" } /** diff --git a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll index be3edb4cd7a..0ee7c10fa7f 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll @@ -42,7 +42,18 @@ module NodeJSLib { * Holds if `call` is an invocation of `http.createServer` or `https.createServer`. */ predicate isCreateServer(CallExpr call) { - call = DataFlow::moduleMember(HTTP::httpOrHttps(), "createServer").getAnInvocation().asExpr() + exists(string pkg, string fn | + pkg = "http" and fn = "createServer" + or + pkg = "https" and fn = "createServer" + or + // http2 compatibility API + pkg = "http2" and fn = "createServer" + or + pkg = "http2" and fn = "createSecureServer" + | + call = DataFlow::moduleMember(pkg, fn).getAnInvocation().asExpr() + ) } /** @@ -356,10 +367,12 @@ module NodeJSLib { /** An expression that is passed as `http.request({ auth: }, ...)`. */ class Credentials extends CredentialsExpr { Credentials() { - this = DataFlow::moduleMember(HTTP::httpOrHttps(), "request") - .getACall() - .getOptionArgument(0, "auth") - .asExpr() + exists(string http | http = "http" or http = "https" | + this = DataFlow::moduleMember(http, "request") + .getACall() + .getOptionArgument(0, "auth") + .asExpr() + ) } override string getCredentialsKind() { result = "credentials" } @@ -881,7 +894,6 @@ module NodeJSLib { override string getSourceType() { result = "NodeJSClientRequest error event" } } - /** * An NodeJS EventEmitter instance. * Events dispatched on this EventEmitter will be handled by event handlers registered on this EventEmitter. diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/createServer.js b/javascript/ql/test/library-tests/frameworks/NodeJSLib/createServer.js index c5a1f5bcd87..5d5e1df1705 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/createServer.js +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/createServer.js @@ -1,3 +1,4 @@ var https = require('https'); https.createServer(function (req, res) {}); https.createServer(o, function (req, res) {}); +require('http2').createServer((req, res) => {}); diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index c676cf9d16e..532c5ccceb4 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -1,6 +1,7 @@ test_isCreateServer | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | | src/http.js:57:1:57:31 | http.cr ... dler()) | @@ -51,6 +52,7 @@ test_HeaderDefinition test_RouteSetup_getServer | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:1:4:47 | require ... => {}) | | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | | src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:1:57:31 | http.cr ... dler()) | @@ -72,6 +74,7 @@ test_HeaderDefinition_getAHeaderName test_ServerDefinition | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | | src/http.js:57:1:57:31 | http.cr ... dler()) | @@ -103,6 +106,7 @@ test_RouteHandler_getAResponseExpr test_ServerDefinition_getARouteHandler | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | @@ -120,6 +124,7 @@ test_ResponseSendArgument test_RouteSetup_getARouteHandler | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | | src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | @@ -147,6 +152,7 @@ test_RemoteFlowSources test_RouteHandler | createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) | | src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | | src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | | src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) |