-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathMissingCsrfMiddleware.ql
More file actions
73 lines (68 loc) · 2.26 KB
/
MissingCsrfMiddleware.ql
File metadata and controls
73 lines (68 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* @name Missing CSRF middleware
* @description Using cookies without CSRF protection may allow malicious websites to
* submit requests on behalf of the user.
* @kind problem
* @problem.severity error
* @precision high
* @id js/missing-token-validation
* @tags security
* external/cwe/cwe-352
*/
import javascript
/**
* Checks if `expr` is preceded by the cookie middleware `cookie`.
*
* A router handler following after cookie parsing is assumed to depend on
* cookies, and thus require CSRF protection.
*/
predicate hasCookieMiddleware(Express::RouteHandlerExpr expr, Express::RouteHandlerExpr cookie) {
any(HTTP::CookieMiddlewareInstance i).flowsToExpr(cookie) and
expr.getAMatchingAncestor() = cookie
}
/**
* Gets an expression that creates a route handler which protects against CSRF attacks.
*
* Any route handler registered downstream from this type of route handler will
* be considered protected.
*
* For example:
* ```
* let csurf = require('csurf');
* let csrfProtector = csurf();
*
* app.post('/changePassword', csrfProtector, function (req, res) {
* // protected from CSRF
* })
* ```
*/
DataFlow::CallNode csrfMiddlewareCreation() {
exists(DataFlow::SourceNode callee | result = callee.getACall() |
callee = DataFlow::moduleImport("csurf")
or
callee = DataFlow::moduleImport("lusca") and
exists(result.getOptionArgument(0, "csrf"))
or
callee = DataFlow::moduleMember("lusca", "csrf")
)
}
/**
* Holds if the given route handler is protected by CSRF middleware.
*/
predicate hasCsrfMiddleware(Express::RouteHandlerExpr handler) {
csrfMiddlewareCreation().flowsToExpr(handler.getAMatchingAncestor())
}
from
Express::RouterDefinition router, Express::RouteSetup setup, Express::RouteHandlerExpr handler,
Express::RouteHandlerExpr cookie
where
router = setup.getRouter() and
handler = setup.getARouteHandlerExpr() and
hasCookieMiddleware(handler, cookie) and
not hasCsrfMiddleware(handler) and
// Only warn for the last handler in a chain.
handler.isLastHandler() and
// Only warn for dangerous for handlers, such as for POST and PUT.
not setup.getRequestMethod().isSafe()
select cookie, "This cookie middleware is serving a request handler $@ without CSRF protection.",
handler, "here"