diff --git a/browserid/app.js b/browserid/app.js index 5b454608791035eb835bbebffa051ce45aa7db0f..9902a49f070f96440ac7924b78c1ecfa353d7897 100644 --- a/browserid/app.js +++ b/browserid/app.js @@ -188,6 +188,24 @@ exports.setup = function(server) { server.use(express.bodyParser()); + // Check CSRF token early. POST requests are only allowed to + // /wsapi and they always must have a valid csrf token + server.use(function(req, resp, next) { + // only on POSTs + if (req.method == "POST") { + if (!/^\/wsapi/.test(req.url) || // post requests only allowed to /wsapi + req.session === undefined || // there must be a session + typeof req.session.csrf !== 'string' || // the session must have a csrf token + req.body.csrf != req.session.csrf) // and the token must match what is sent in the post body + { + // if any of these things are false, then we'll block the request + logger.warn("CSRF validation failure."); + return httputils.badRequest(resp, "CSRF violation"); + } + } + return next(); + }); + // a tweak to get the content type of host-meta correct server.use(function(req, resp, next) { if (req.url === '/.well-known/host-meta') { diff --git a/browserid/lib/wsapi.js b/browserid/lib/wsapi.js index d65382a9d1f252506e39c2ed01197dd626c7e734..2b4c6b1ec9f4d8082fa3f431571cdae10604f93d 100644 --- a/browserid/lib/wsapi.js +++ b/browserid/lib/wsapi.js @@ -85,19 +85,6 @@ function checkAuthed(req, resp, next) { } function setup(app) { - // check CSRF token before routing the request to the proper handler - // (iff the request is to /wsapi AND it's a post) - app.use(function(req, resp, next) { - // only on POSTs to /wsapi - if (req.method == "POST" && /^\/wsapi/.test(req.url) && req.body.csrf != req.session.csrf) { - // error, problem with CSRF - logger.warn("CSRF token mismatch. got:" + req.body.csrf + " wanted:" + req.session.csrf); - httputils.badRequest(resp, "CSRF violation"); - } else { - next(); - } - }); - // return the CSRF token // IMPORTANT: this should be safe because it's only readable by same-origin code // but we must be careful that this is never a JSON structure that could be hijacked