Skip to content

Commit d84f1b4

Browse files
committed
JS: Refactor RequestInputAccess to use source nodes
1 parent da974f1 commit d84f1b4

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

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

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -461,28 +461,21 @@ module Express {
461461
string kind;
462462

463463
RequestInputAccess() {
464-
exists(DataFlow::Node request | request = DataFlow::valueNode(rh.getARequestExpr()) |
464+
exists(DataFlow::SourceNode request | request = rh.getARequestSource().ref() |
465465
kind = "parameter" and
466466
(
467-
this.(DataFlow::MethodCallNode).calls(request, "param")
467+
this = request.getAMethodCall("param")
468468
or
469-
exists(DataFlow::PropRead base, string propName |
470-
// `req.params.name` or `req.query.name`
471-
base.accesses(request, propName) and
472-
this = base.getAPropertyReference(_)
473-
|
474-
propName = "params" or
475-
propName = "query"
476-
)
469+
this = request.getAPropertyRead(["params", "query"]).getAPropertyRead()
477470
)
478471
or
479472
// `req.originalUrl`
480473
kind = "url" and
481-
this.(DataFlow::PropRef).accesses(request, "originalUrl")
474+
this = request.getAPropertyRead("originalUrl")
482475
or
483476
// `req.cookies`
484477
kind = "cookie" and
485-
this.(DataFlow::PropRef).accesses(request, "cookies")
478+
this = request.getAPropertyRead("cookies")
486479
)
487480
or
488481
kind = "body" and

javascript/ql/src/semmle/javascript/frameworks/HTTP.qll

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,24 @@ module HTTP {
204204
*/
205205
abstract HeaderDefinition getAResponseHeader(string name);
206206

207+
/**
208+
* Gets a request object originating from this route handler.
209+
*
210+
* Use `RequestSource.ref()` to get reference to this request object.
211+
*/
212+
final Servers::RequestSource getARequestSource() {
213+
result.getRouteHandler() = this
214+
}
215+
216+
/**
217+
* Gets a request object originating from this route handler.
218+
*
219+
* Use `RequestSource.ref()` to get reference to this request object.
220+
*/
221+
final Servers::ResponseSource getAResponseSource() {
222+
result.getRouteHandler() = this
223+
}
224+
207225
/**
208226
* Gets an expression that contains a request object handled
209227
* by this handler.
@@ -296,14 +314,21 @@ module HTTP {
296314
*/
297315
abstract RouteHandler getRouteHandler();
298316

299-
predicate flowsTo(DataFlow::Node nd) { ref(DataFlow::TypeTracker::end()).flowsTo(nd) }
317+
/** DEPRECATED. Use `ref().flowsTo()` instead. */
318+
deprecated
319+
predicate flowsTo(DataFlow::Node nd) { ref().flowsTo(nd) }
300320

301321
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
302322
t.start() and
303323
result = this
304324
or
305325
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
306326
}
327+
328+
/** Gets a `SourceNode` that refers to this request object. */
329+
DataFlow::SourceNode ref() {
330+
result = ref(DataFlow::TypeTracker::end())
331+
}
307332
}
308333

309334
/**
@@ -317,14 +342,20 @@ module HTTP {
317342
*/
318343
abstract RouteHandler getRouteHandler();
319344

320-
predicate flowsTo(DataFlow::Node nd) { ref(DataFlow::TypeTracker::end()).flowsTo(nd) }
345+
/** DEPRECATED. Use `ref().flowsTo()` instead. */
346+
predicate flowsTo(DataFlow::Node nd) { ref().flowsTo(nd) }
321347

322348
private DataFlow::SourceNode ref(DataFlow::TypeTracker t) {
323349
t.start() and
324350
result = this
325351
or
326352
exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t))
327353
}
354+
355+
/** Gets a `SourceNode` that refers to this response object. */
356+
DataFlow::SourceNode ref() {
357+
result = ref(DataFlow::TypeTracker::end())
358+
}
328359
}
329360

330361
/**
@@ -333,7 +364,7 @@ module HTTP {
333364
class StandardRequestExpr extends RequestExpr {
334365
RequestSource src;
335366

336-
StandardRequestExpr() { src.flowsTo(DataFlow::valueNode(this)) }
367+
StandardRequestExpr() { src.ref().flowsTo(DataFlow::valueNode(this)) }
337368

338369
override RouteHandler getRouteHandler() { result = src.getRouteHandler() }
339370
}
@@ -344,7 +375,7 @@ module HTTP {
344375
class StandardResponseExpr extends ResponseExpr {
345376
ResponseSource src;
346377

347-
StandardResponseExpr() { src.flowsTo(DataFlow::valueNode(this)) }
378+
StandardResponseExpr() { src.ref().flowsTo(DataFlow::valueNode(this)) }
348379

349380
override RouteHandler getRouteHandler() { result = src.getRouteHandler() }
350381
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ test_RequestInputAccess
279279
| src/express3.js:5:35:5:50 | req.param("val") | parameter | src/express3.js:4:23:7:1 | functio ... al");\\n} |
280280
| src/express4.js:5:9:5:11 | foo | parameter | src/express4.js:4:23:9:1 | functio ... ic1);\\n} |
281281
| src/express4.js:5:14:5:21 | bar: baz | parameter | src/express4.js:4:23:9:1 | functio ... ic1);\\n} |
282+
| src/express4.js:6:18:6:31 | req.query[foo] | parameter | src/express4.js:4:23:9:1 | functio ... ic1);\\n} |
283+
| src/express4.js:7:18:7:39 | req.que ... hing()] | parameter | src/express4.js:4:23:9:1 | functio ... ic1);\\n} |
282284
| src/express.js:5:16:5:34 | req.param("target") | parameter | src/express.js:4:23:9:1 | functio ... res);\\n} |
283285
| src/express.js:6:26:6:44 | req.param("target") | parameter | src/express.js:4:23:9:1 | functio ... res);\\n} |
284286
| src/express.js:23:3:23:10 | req.body | body | src/express.js:22:30:32:1 | functio ... ar');\\n} |

0 commit comments

Comments
 (0)