Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7ea8652

Browse files
authored
Merge pull request #4521 from erik-krogh/moreMiddle
Approved by asgerf
2 parents 17155b6 + e061c6a commit 7ea8652

2 files changed

Lines changed: 41 additions & 11 deletions

File tree

javascript/ql/src/Security/CWE-352/MissingCsrfMiddleware.ql

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,21 @@ DataFlow::CallNode csrfMiddlewareCreation() {
100100
}
101101

102102
/**
103-
* Gets a data flow node that flows to the base of a write to `cookies`, `session`, or `user`,
104-
* where the written property has `csrf` or `xsrf` in its name.
103+
* Gets a data flow node that flows to the base of a reference to `cookies`, `session`, or `user`,
104+
* where the references property has `csrf` or `xsrf` in its name,
105+
* and a property is either written or part of a comparison.
105106
*/
106-
private DataFlow::SourceNode nodeLeadingToCsrfWrite(DataFlow::TypeBackTracker t) {
107+
private DataFlow::SourceNode nodeLeadingToCsrfWriteOrCheck(DataFlow::TypeBackTracker t) {
107108
t.start() and
108-
result
109-
.getAPropertyRead(cookieProperty())
110-
.getAPropertyWrite()
111-
.getPropertyName()
112-
.regexpMatch("(?i).*(csrf|xsrf).*")
109+
exists(DataFlow::PropRef ref |
110+
ref = result.getAPropertyRead(cookieProperty()).getAPropertyReference() and
111+
ref.getPropertyName().regexpMatch("(?i).*(csrf|xsrf).*")
112+
|
113+
ref instanceof DataFlow::PropWrite or
114+
ref.(DataFlow::PropRead).asExpr() = any(EqualityTest c).getAnOperand()
115+
)
113116
or
114-
exists(DataFlow::TypeBackTracker t2 | result = nodeLeadingToCsrfWrite(t2).backtrack(t2, t))
117+
exists(DataFlow::TypeBackTracker t2 | result = nodeLeadingToCsrfWriteOrCheck(t2).backtrack(t2, t))
115118
}
116119

117120
/**
@@ -131,7 +134,7 @@ private Express::RouteHandler getAHandlerSettingCsrfCookie() {
131134
*/
132135
predicate isCsrfProtectionRouteHandler(Express::RouteHandler handler) {
133136
DataFlow::parameterNode(handler.getRequestParameter()) =
134-
nodeLeadingToCsrfWrite(DataFlow::TypeBackTracker::end())
137+
nodeLeadingToCsrfWriteOrCheck(DataFlow::TypeBackTracker::end())
135138
or
136139
handler = getAHandlerSettingCsrfCookie()
137140
}

javascript/ql/test/query-tests/Security/CWE-352/MissingCsrfMiddlewareGood2.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,31 @@ var passport = require('passport');
8989
app.post('/changeEmail', function (req, res) {
9090
let newEmail = req.cookies["newEmail"];
9191
})
92-
});
92+
});
93+
94+
95+
(function () {
96+
var app = express()
97+
98+
app.use(cookieParser())
99+
app.use(passport.authorize({ session: true }))
100+
101+
function checkToken(req) {
102+
if (req.headers.xsrfToken !== req.session.xsrfToken) {
103+
throw new Error("Halt and catch fire!")
104+
}
105+
}
106+
107+
function setCsrfToken(req, response, next) {
108+
req.session.xsrfToken = req.csrfToken();
109+
next();
110+
}
111+
112+
app.use(checkToken);
113+
114+
app.post('/changeEmail', function (req, res) {
115+
let newEmail = req.cookies["newEmail"];
116+
});
117+
118+
app.use(setCsrfToken); // There is nothing wrong with setting the token late, as long as it is checked early.
119+
});

0 commit comments

Comments
 (0)