Skip to content

Commit 13d2453

Browse files
committed
JS: Add GuardedRouteHandler access path component
1 parent fdea22f commit 13d2453

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,20 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathTokenBase token) {
184184
or
185185
token.getName() = "DecoratedParameter" and
186186
result = node.getADecoratedParameter()
187+
or
188+
token.getName() = "GuardedRouteHandler" and
189+
result = getAGuardedRouteHandlerApprox(node)
190+
}
191+
192+
bindingset[node]
193+
pragma[inline_late]
194+
private API::Node getAGuardedRouteHandlerApprox(API::Node node) {
195+
// For now just get any routing node with the same root (i.e. the same web app), as
196+
// there are some known performance issues when checking if it is actually guarded by the given node.
197+
exists(JS::Routing::Node root |
198+
root = JS::Routing::getNode(node.getAValueReachableFromSource()).getRootNode() and
199+
root = JS::Routing::getNode(result.asSink()).getRootNode()
200+
)
187201
}
188202

189203
/**
@@ -317,7 +331,7 @@ predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
317331
[
318332
"Member", "AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue",
319333
"NewCall", "Call", "DecoratedClass", "DecoratedMember", "DecoratedParameter",
320-
"WithStringArgument"
334+
"WithStringArgument", "GuardedRouteHandler"
321335
]
322336
}
323337

@@ -329,7 +343,7 @@ predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
329343
name =
330344
[
331345
"AnyMember", "Instance", "Awaited", "ArrayElement", "Element", "MapValue", "NewCall", "Call",
332-
"DecoratedClass", "DecoratedMember", "DecoratedParameter"
346+
"DecoratedClass", "DecoratedMember", "DecoratedParameter", "GuardedRouteHandler"
333347
]
334348
}
335349

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const express = require('express');
2+
const app = express();
3+
const testlib = require('testlib');
4+
5+
app.get('/before', (req, res) => {
6+
sink(req.injectedReqData); // OK [INCONSISTENCY] - happens before middleware
7+
sink(req.injectedResData); // OK - wrong parameter
8+
9+
sink(res.injectedReqData); // OK - wrong parameter
10+
sink(res.injectedResData); // OK [INCONSISTENCY] - happens before middleware
11+
});
12+
13+
app.use(testlib.middleware());
14+
15+
app.get('/after', (req, res) => {
16+
sink(req.injectedReqData); // NOT OK
17+
sink(req.injectedResData); // OK - wrong parameter
18+
19+
sink(res.injectedReqData); // OK - wrong parameter
20+
sink(res.injectedResData); // NOT OK
21+
});

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
legacyDataFlowDifference
22
consistencyIssue
33
taintFlow
4+
| guardedRouteHandler.js:6:10:6:28 | req.injectedReqData | guardedRouteHandler.js:6:10:6:28 | req.injectedReqData |
5+
| guardedRouteHandler.js:10:10:10:28 | res.injectedResData | guardedRouteHandler.js:10:10:10:28 | res.injectedResData |
6+
| guardedRouteHandler.js:16:10:16:28 | req.injectedReqData | guardedRouteHandler.js:16:10:16:28 | req.injectedReqData |
7+
| guardedRouteHandler.js:20:10:20:28 | res.injectedResData | guardedRouteHandler.js:20:10:20:28 | res.injectedResData |
48
| paramDecorator.ts:6:54:6:54 | x | paramDecorator.ts:7:10:7:10 | x |
59
| test.js:5:30:5:37 | source() | test.js:5:8:5:38 | testlib ... urce()) |
610
| test.js:6:22:6:29 | source() | test.js:6:8:6:30 | preserv ... urce()) |

javascript/ql/test/library-tests/frameworks/data/test.ext.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ extensions:
1313
- ['testlib', 'Member[getSourceArray].ReturnValue.ArrayElement', 'test-source']
1414
- ['(testlib)', 'Member[parenthesizedPackageName].ReturnValue', 'test-source']
1515
- ['danger-constant', 'Member[danger]', 'test-source']
16+
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[0].Member[injectedReqData]', 'test-source']
17+
- ['testlib', 'Member[middleware].ReturnValue.GuardedRouteHandler.Parameter[1].Member[injectedResData]', 'test-source']
1618

1719
- addsTo:
1820
pack: codeql/javascript-all

0 commit comments

Comments
 (0)