From d4d910b68127f5182297cd7c0c0a1940b4a7cc9f Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Wed, 29 Jan 2020 14:37:40 +0100 Subject: [PATCH 1/3] JS: add koa test --- javascript/ql/test/library-tests/frameworks/koa/src/koa.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/javascript/ql/test/library-tests/frameworks/koa/src/koa.js b/javascript/ql/test/library-tests/frameworks/koa/src/koa.js index 24680a4a746..479298fd405 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/src/koa.js +++ b/javascript/ql/test/library-tests/frameworks/koa/src/koa.js @@ -54,3 +54,8 @@ app2.use(async ctx => { var headers = ctx.headers; headers.foo; }); + +var app3 = Koa(); +app3.use(function*(){ + this.request.url; +}); From a6d3afd81797afc0ea906d6d1b0c05cbbc6f72a0 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Wed, 29 Jan 2020 14:42:17 +0100 Subject: [PATCH 2/3] JS: support additional Koa request sources --- change-notes/1.24/analysis-javascript.md | 1 + .../src/semmle/javascript/frameworks/Koa.qll | 22 ++++++++++++++++++- .../frameworks/koa/tests.expected | 10 +++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/change-notes/1.24/analysis-javascript.md b/change-notes/1.24/analysis-javascript.md index d367d235a8c..21411b01179 100644 --- a/change-notes/1.24/analysis-javascript.md +++ b/change-notes/1.24/analysis-javascript.md @@ -18,6 +18,7 @@ - [Socket.IO](https://socket.io/) - [ws](https://github.com/websockets/ws) - [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) + - [Koa](https://www.npmjs.com/package/koa) ## New queries diff --git a/javascript/ql/src/semmle/javascript/frameworks/Koa.qll b/javascript/ql/src/semmle/javascript/frameworks/Koa.qll index ca38db8429e..bcc47bad9eb 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Koa.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Koa.qll @@ -9,7 +9,7 @@ module Koa { /** * An expression that creates a new Koa application. */ - class AppDefinition extends HTTP::Servers::StandardServerDefinition, NewExpr { + class AppDefinition extends HTTP::Servers::StandardServerDefinition, InvokeExpr { AppDefinition() { // `app = new Koa()` this = DataFlow::moduleImport("koa").getAnInvocation().asExpr() @@ -115,6 +115,26 @@ module Koa { override RouteHandler getRouteHandler() { result = ctx.getRouteHandler() } } + /** + * A Koa request source, accessed through the a request property of a + * generator route handler (deprecated in Koa 3). + */ + private class GeneratorRequestSource extends HTTP::Servers::RequestSource { + RouteHandler rh; + + GeneratorRequestSource() { + exists(DataFlow::FunctionNode fun | fun = rh | + fun.getFunction().isGenerator() and + fun.getReceiver().getAPropertyRead("request") = this + ) + } + + /** + * Gets the route handler that provides this response. + */ + override RouteHandler getRouteHandler() { result = rh } + } + /** * A Koa response source, that is, an access to the `response` property * of a context object. diff --git a/javascript/ql/test/library-tests/frameworks/koa/tests.expected b/javascript/ql/test/library-tests/frameworks/koa/tests.expected index 0d8e37d13a6..8e6f1aa06a2 100644 --- a/javascript/ql/test/library-tests/frameworks/koa/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/koa/tests.expected @@ -3,6 +3,7 @@ test_RouteSetup | src/koa.js:10:1:28:2 | app2.us ... z');\\n}) | | src/koa.js:30:1:45:2 | app2.us ... rl);\\n}) | | src/koa.js:47:1:56:2 | app2.us ... foo;\\n}) | +| src/koa.js:59:1:61:2 | app3.us ... url;\\n}) | test_RequestInputAccess | src/koa.js:19:3:19:18 | ctx.request.body | body | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:20:3:20:23 | ctx.req ... ery.foo | parameter | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -24,6 +25,7 @@ test_RequestInputAccess | src/koa.js:49:2:49:14 | cookies.get() | cookie | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:52:2:52:10 | query.foo | parameter | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:55:2:55:12 | headers.foo | header | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | +| src/koa.js:60:2:60:17 | this.request.url | url | src/koa.js:59:10:61:1 | functio ... .url;\\n} | test_RouteHandler_getAResponseHeader | src/koa.js:10:10:28:1 | functio ... az');\\n} | header1 | src/koa.js:11:3:11:25 | this.se ... 1', '') | | src/koa.js:10:10:28:1 | functio ... az');\\n} | header2 | src/koa.js:12:3:12:37 | this.re ... 2', '') | @@ -75,6 +77,7 @@ test_RouteHandler_getAContextExpr | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:48:16:48:18 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:51:14:51:16 | ctx | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:54:16:54:18 | ctx | +| src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:60:2:60:5 | this | test_HeaderDefinition | src/koa.js:11:3:11:25 | this.se ... 1', '') | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:12:3:12:37 | this.re ... 2', '') | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -87,6 +90,7 @@ test_RouteSetup_getServer | src/koa.js:10:1:28:2 | app2.us ... z');\\n}) | src/koa.js:5:12:5:20 | new Koa() | | src/koa.js:30:1:45:2 | app2.us ... rl);\\n}) | src/koa.js:5:12:5:20 | new Koa() | | src/koa.js:47:1:56:2 | app2.us ... foo;\\n}) | src/koa.js:5:12:5:20 | new Koa() | +| src/koa.js:59:1:61:2 | app3.us ... url;\\n}) | src/koa.js:58:12:58:16 | Koa() | test_HeaderDefinition_getAHeaderName | src/koa.js:11:3:11:25 | this.se ... 1', '') | header1 | | src/koa.js:12:3:12:37 | this.re ... 2', '') | header2 | @@ -116,14 +120,17 @@ test_RouteSetup_getARouteHandler | src/koa.js:10:1:28:2 | app2.us ... z');\\n}) | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:30:1:45:2 | app2.us ... rl);\\n}) | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:47:1:56:2 | app2.us ... foo;\\n}) | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | +| src/koa.js:59:1:61:2 | app3.us ... url;\\n}) | src/koa.js:59:10:61:1 | functio ... .url;\\n} | test_AppDefinition | src/koa.js:2:12:2:33 | new (re ... oa'))() | | src/koa.js:5:12:5:20 | new Koa() | +| src/koa.js:58:12:58:16 | Koa() | test_RouteHandler | src/koa.js:7:1:7:22 | functio ... r1() {} | src/koa.js:5:12:5:20 | new Koa() | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:5:12:5:20 | new Koa() | | src/koa.js:30:10:45:1 | async c ... url);\\n} | src/koa.js:5:12:5:20 | new Koa() | | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | src/koa.js:5:12:5:20 | new Koa() | +| src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:58:12:58:16 | Koa() | test_RequestExpr | src/koa.js:19:3:19:13 | ctx.request | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:20:3:20:13 | ctx.request | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -133,6 +140,7 @@ test_RequestExpr | src/koa.js:24:3:24:13 | ctx.request | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:25:3:25:13 | ctx.request | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:26:3:26:13 | ctx.request | src/koa.js:10:10:28:1 | functio ... az');\\n} | +| src/koa.js:60:2:60:13 | this.request | src/koa.js:59:10:61:1 | functio ... .url;\\n} | test_RouteHandler_getARequestExpr | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:19:3:19:13 | ctx.request | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:20:3:20:13 | ctx.request | @@ -142,6 +150,7 @@ test_RouteHandler_getARequestExpr | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:24:3:24:13 | ctx.request | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:25:3:25:13 | ctx.request | | src/koa.js:10:10:28:1 | functio ... az');\\n} | src/koa.js:26:3:26:13 | ctx.request | +| src/koa.js:59:10:61:1 | functio ... .url;\\n} | src/koa.js:60:2:60:13 | this.request | test_ContextExpr | src/koa.js:11:3:11:6 | this | src/koa.js:10:10:28:1 | functio ... az');\\n} | | src/koa.js:12:3:12:6 | this | src/koa.js:10:10:28:1 | functio ... az');\\n} | @@ -174,6 +183,7 @@ test_ContextExpr | src/koa.js:48:16:48:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:51:14:51:16 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | | src/koa.js:54:16:54:18 | ctx | src/koa.js:47:10:56:1 | async c ... .foo;\\n} | +| src/koa.js:60:2:60:5 | this | src/koa.js:59:10:61:1 | functio ... .url;\\n} | test_RedirectInvocation | src/koa.js:43:2:43:18 | ctx.redirect(url) | src/koa.js:43:15:43:17 | url | src/koa.js:30:10:45:1 | async c ... url);\\n} | | src/koa.js:44:2:44:27 | ctx.res ... ct(url) | src/koa.js:44:24:44:26 | url | src/koa.js:30:10:45:1 | async c ... url);\\n} | From 31743c42e51f358130764ed4c7d5bae1e650b970 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Wed, 29 Jan 2020 20:28:29 +0100 Subject: [PATCH 3/3] Update javascript/ql/src/semmle/javascript/frameworks/Koa.qll Co-Authored-By: Erik Krogh Kristensen --- javascript/ql/src/semmle/javascript/frameworks/Koa.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Koa.qll b/javascript/ql/src/semmle/javascript/frameworks/Koa.qll index bcc47bad9eb..ab306964ebe 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Koa.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Koa.qll @@ -11,7 +11,7 @@ module Koa { */ class AppDefinition extends HTTP::Servers::StandardServerDefinition, InvokeExpr { AppDefinition() { - // `app = new Koa()` + // `app = new Koa()` / `app = Koa()` this = DataFlow::moduleImport("koa").getAnInvocation().asExpr() } }