Skip to content

Commit 32369da

Browse files
authored
Merge pull request #19124 from Napalys/js/hapi_upgrade
JS: Support for newer version of `Hapi` - `@hapi/hapi`
2 parents e2ed848 + a78e0e9 commit 32369da

File tree

6 files changed

+132
-2
lines changed

6 files changed

+132
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added support for the newer version of `Hapi` with the `@hapi/hapi` import and `server` function.

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ module Hapi {
1111
*/
1212
class ServerDefinition extends Http::Servers::StandardServerDefinition, DataFlow::Node {
1313
ServerDefinition() {
14-
// `server = new Hapi.Server()`
15-
this = DataFlow::moduleMember("hapi", "Server").getAnInstantiation()
14+
// `server = new Hapi.Server()`, `server = Hapi.server()`
15+
this = DataFlow::moduleMember(["hapi", "@hapi/hapi"], ["Server", "server"]).getAnInvocation()
1616
or
1717
// `server = Glue.compose(manifest, composeOptions)`
1818
this = DataFlow::moduleMember("@hapi/glue", "compose").getAnInvocation()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
var server1 = new (require('@hapi/hapi')).Server(); // HTTP::Server
2+
3+
var Hapi = require('@hapi/hapi');
4+
var server2 = new Hapi.Server(); // HTTP::Server
5+
6+
function handler1(){} // HTTP::RouteHandler
7+
server2.route({
8+
handler: handler1
9+
});
10+
11+
12+
server2.route({
13+
handler: function handler2(request, reply){ // HTTP::RouteHandler
14+
request.response.header('HEADER1', '') // HTTP::HeaderDefinition
15+
}});
16+
17+
server2.ext('onPreResponse', function handler3(request, reply) { // HTTP::RouteHandler
18+
})
19+
20+
function handler4(request, reply){
21+
request.rawPayload;
22+
request.payload.foo;
23+
request.query.bar;
24+
request.url.path;
25+
request.headers.baz;
26+
request.state.token;
27+
}
28+
var route = {handler: handler4};
29+
server2.route(route);
30+
31+
server2.cache({ segment: 'countries', expiresIn: 60*60*1000 });
32+
33+
function getHandler() {
34+
return function (req, h){}
35+
}
36+
server2.route({handler: getHandler()});

javascript/ql/test/library-tests/frameworks/hapi/tests.expected

+62
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ test_RouteSetup
99
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) |
1010
| src/hapiglue.js:31:1:31:20 | server2.route(route) |
1111
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) |
12+
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) |
13+
| src/hapihapi.js:12:1:15:7 | server2 ... }}) |
14+
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) |
15+
| src/hapihapi.js:29:1:29:20 | server2.route(route) |
16+
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) |
1217
test_RequestExpr
1318
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
1419
| src/hapi.js:13:32:13:38 | request | src/hapi.js:13:14:15:5 | functio ... n\\n } |
@@ -38,12 +43,27 @@ test_RequestExpr
3843
| src/hapiglue.js:27:3:27:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
3944
| src/hapiglue.js:28:3:28:9 | request | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
4045
| src/hapiglue.js:36:22:36:24 | req | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
46+
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
47+
| src/hapihapi.js:13:32:13:38 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
48+
| src/hapihapi.js:14:9:14:15 | request | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
49+
| src/hapihapi.js:17:48:17:54 | request | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
50+
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
51+
| src/hapihapi.js:20:19:20:25 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
52+
| src/hapihapi.js:21:3:21:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
53+
| src/hapihapi.js:22:3:22:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
54+
| src/hapihapi.js:23:3:23:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
55+
| src/hapihapi.js:24:3:24:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
56+
| src/hapihapi.js:25:3:25:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
57+
| src/hapihapi.js:26:3:26:9 | request | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
58+
| src/hapihapi.js:34:22:34:24 | req | src/hapihapi.js:34:12:34:30 | function (req, h){} |
4159
test_HeaderAccess
4260
| src/hapi.js:25:3:25:21 | request.headers.baz | baz |
4361
| src/hapiglue.js:27:3:27:21 | request.headers.baz | baz |
62+
| src/hapihapi.js:25:3:25:21 | request.headers.baz | baz |
4463
test_ResponseExpr
4564
| src/hapi.js:14:9:14:24 | request.response | src/hapi.js:13:14:15:5 | functio ... n\\n } |
4665
| src/hapiglue.js:14:9:14:24 | request.response | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
66+
| src/hapihapi.js:14:9:14:24 | request.response | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
4767
test_RouteHandler
4868
| src/hapi.js:6:1:6:21 | functio ... er1(){} | src/hapi.js:4:15:4:31 | new Hapi.Server() |
4969
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:4:15:4:31 | new Hapi.Server() |
@@ -55,16 +75,24 @@ test_RouteHandler
5575
| src/hapiglue.js:17:30:18:1 | functio ... ndler\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
5676
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
5777
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
78+
| src/hapihapi.js:6:1:6:21 | functio ... er1(){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
79+
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
80+
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
81+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
82+
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
5883
test_HeaderDefinition
5984
| src/hapi.js:14:9:14:46 | request ... 1', '') | src/hapi.js:13:14:15:5 | functio ... n\\n } |
6085
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | src/hapiglue.js:13:14:15:5 | functio ... n\\n } |
86+
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
6187
test_ServerDefinition
6288
| src/hapi.js:1:15:1:44 | new (re ... erver() |
6389
| src/hapi.js:4:15:4:31 | new Hapi.Server() |
6490
| src/hapiglue.js:1:15:1:88 | new (re ... ptions) |
6591
| src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
6692
| src/hapiglue.js:43:19:43:24 | server |
6793
| src/hapiglue.js:44:45:44:51 | server_ |
94+
| src/hapihapi.js:1:15:1:50 | new (re ... erver() |
95+
| src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
6896
test_RequestInputAccess
6997
| src/hapi.js:21:3:21:20 | request.rawPayload | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
7098
| src/hapi.js:22:3:22:21 | request.payload.foo | body | src/hapi.js:20:1:27:1 | functio ... oken;\\n} |
@@ -80,6 +108,12 @@ test_RequestInputAccess
80108
| src/hapiglue.js:26:3:26:20 | request.url.origin | url | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
81109
| src/hapiglue.js:27:3:27:21 | request.headers.baz | header | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
82110
| src/hapiglue.js:28:3:28:21 | request.state.token | cookie | src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} |
111+
| src/hapihapi.js:21:3:21:20 | request.rawPayload | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
112+
| src/hapihapi.js:22:3:22:21 | request.payload.foo | body | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
113+
| src/hapihapi.js:23:3:23:19 | request.query.bar | parameter | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
114+
| src/hapihapi.js:24:3:24:18 | request.url.path | url | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
115+
| src/hapihapi.js:25:3:25:21 | request.headers.baz | header | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
116+
| src/hapihapi.js:26:3:26:21 | request.state.token | cookie | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
83117
test_RouteSetup_getServer
84118
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
85119
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:4:15:4:31 | new Hapi.Server() |
@@ -91,9 +125,15 @@ test_RouteSetup_getServer
91125
| src/hapiglue.js:17:1:18:2 | server2 ... dler\\n}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
92126
| src/hapiglue.js:31:1:31:20 | server2.route(route) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
93127
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:4:15:4:69 | new Hap ... ptions) |
128+
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
129+
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
130+
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
131+
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
132+
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:4:15:4:31 | new Hapi.Server() |
94133
test_HeaderDefinition_defines
95134
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 | |
96135
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 | |
136+
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 | |
97137
test_RouteSetup_getARouteHandler
98138
| src/hapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapi.js:6:1:6:21 | functio ... er1(){} |
99139
| src/hapi.js:12:1:15:7 | server2 ... }}) | src/hapi.js:13:14:15:5 | functio ... n\\n } |
@@ -109,6 +149,13 @@ test_RouteSetup_getARouteHandler
109149
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:35:1:37:1 | return of function getHandler |
110150
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:36:12:36:33 | functio ... hapi){} |
111151
| src/hapiglue.js:38:1:38:38 | server2 ... ler()}) | src/hapiglue.js:38:25:38:36 | getHandler() |
152+
| src/hapihapi.js:7:1:9:2 | server2 ... ler1\\n}) | src/hapihapi.js:6:1:6:21 | functio ... er1(){} |
153+
| src/hapihapi.js:12:1:15:7 | server2 ... }}) | src/hapihapi.js:13:14:15:5 | functio ... n\\n } |
154+
| src/hapihapi.js:17:1:18:2 | server2 ... dler\\n}) | src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} |
155+
| src/hapihapi.js:29:1:29:20 | server2.route(route) | src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} |
156+
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:33:1:35:1 | return of function getHandler |
157+
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:34:12:34:30 | function (req, h){} |
158+
| src/hapihapi.js:36:1:36:38 | server2 ... ler()}) | src/hapihapi.js:36:25:36:36 | getHandler() |
112159
test_RouteHandler_getARequestExpr
113160
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
114161
| src/hapi.js:13:14:15:5 | functio ... n\\n } | src/hapi.js:13:32:13:38 | request |
@@ -138,9 +185,24 @@ test_RouteHandler_getARequestExpr
138185
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:27:3:27:9 | request |
139186
| src/hapiglue.js:20:1:29:1 | functio ... oken;\\n} | src/hapiglue.js:28:3:28:9 | request |
140187
| src/hapiglue.js:36:12:36:33 | functio ... hapi){} | src/hapiglue.js:36:22:36:24 | req |
188+
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
189+
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:13:32:13:38 | request |
190+
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | src/hapihapi.js:14:9:14:15 | request |
191+
| src/hapihapi.js:17:30:18:1 | functio ... ndler\\n} | src/hapihapi.js:17:48:17:54 | request |
192+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
193+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:20:19:20:25 | request |
194+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:21:3:21:9 | request |
195+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:22:3:22:9 | request |
196+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:23:3:23:9 | request |
197+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:24:3:24:9 | request |
198+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:25:3:25:9 | request |
199+
| src/hapihapi.js:20:1:27:1 | functio ... oken;\\n} | src/hapihapi.js:26:3:26:9 | request |
200+
| src/hapihapi.js:34:12:34:30 | function (req, h){} | src/hapihapi.js:34:22:34:24 | req |
141201
test_HeaderDefinition_getAHeaderName
142202
| src/hapi.js:14:9:14:46 | request ... 1', '') | header1 |
143203
| src/hapiglue.js:14:9:14:46 | request ... 1', '') | header1 |
204+
| src/hapihapi.js:14:9:14:46 | request ... 1', '') | header1 |
144205
test_RouteHandler_getAResponseHeader
145206
| src/hapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapi.js:14:9:14:46 | request ... 1', '') |
146207
| src/hapiglue.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapiglue.js:14:9:14:46 | request ... 1', '') |
208+
| src/hapihapi.js:13:14:15:5 | functio ... n\\n } | header1 | src/hapihapi.js:14:9:14:46 | request ... 1', '') |

javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value |
5252
| handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value |
5353
| handlebars.js:15:25:15:32 | filePath | handlebars.js:43:15:43:29 | req.params.path | handlebars.js:15:25:15:32 | filePath | This path depends on a $@. | handlebars.js:43:15:43:29 | req.params.path | user-provided value |
54+
| hapi.js:15:44:15:51 | filepath | hapi.js:14:30:14:51 | request ... ilepath | hapi.js:15:44:15:51 | filepath | This path depends on a $@. | hapi.js:14:30:14:51 | request ... ilepath | user-provided value |
5455
| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
5556
| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
5657
| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on a $@. | normalizedPaths.js:11:14:11:27 | req.query.path | user-provided value |
@@ -344,6 +345,8 @@ edges
344345
| handlebars.js:13:73:13:80 | filePath | handlebars.js:15:25:15:32 | filePath | provenance | |
345346
| handlebars.js:29:46:29:60 | req.params.path | handlebars.js:10:51:10:58 | filePath | provenance | |
346347
| handlebars.js:43:15:43:29 | req.params.path | handlebars.js:13:73:13:80 | filePath | provenance | |
348+
| hapi.js:14:19:14:51 | filepath | hapi.js:15:44:15:51 | filepath | provenance | |
349+
| hapi.js:14:30:14:51 | request ... ilepath | hapi.js:14:19:14:51 | filepath | provenance | |
347350
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | provenance | |
348351
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:14:26:14:29 | path | provenance | |
349352
| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:15:19:15:22 | path | provenance | |
@@ -821,6 +824,9 @@ nodes
821824
| handlebars.js:15:25:15:32 | filePath | semmle.label | filePath |
822825
| handlebars.js:29:46:29:60 | req.params.path | semmle.label | req.params.path |
823826
| handlebars.js:43:15:43:29 | req.params.path | semmle.label | req.params.path |
827+
| hapi.js:14:19:14:51 | filepath | semmle.label | filepath |
828+
| hapi.js:14:30:14:51 | request ... ilepath | semmle.label | request ... ilepath |
829+
| hapi.js:15:44:15:51 | filepath | semmle.label | filepath |
824830
| normalizedPaths.js:11:7:11:27 | path | semmle.label | path |
825831
| normalizedPaths.js:11:14:11:27 | req.query.path | semmle.label | req.query.path |
826832
| normalizedPaths.js:13:19:13:22 | path | semmle.label | path |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const Hapi = require('@hapi/hapi');
2+
const fs = require('fs').promises;
3+
4+
(async () => {
5+
const server = Hapi.server({
6+
port: 3005,
7+
host: 'localhost'
8+
});
9+
10+
server.route({
11+
method: 'GET',
12+
path: '/hello',
13+
handler: async (request, h) => {
14+
const filepath = request.query.filepath; // $ Source
15+
const data = await fs.readFile(filepath, 'utf8'); // $ Alert
16+
const firstLine = data.split('\n')[0];
17+
return firstLine;
18+
}
19+
});
20+
21+
await server.start();
22+
})();

0 commit comments

Comments
 (0)