Fixing CSRF middleware for whitelisting

This commit is contained in:
Andrew Hayward 2013-05-31 15:15:31 +01:00
Родитель 45f8486e3e
Коммит dde9a17ff8
2 изменённых файлов: 60 добавлений и 1 удалений

6
app.js
Просмотреть файл

@ -13,6 +13,11 @@ env.express(app);
app.use(express.cookieParser());
app.use(middleware.session());
app.use(middleware.csrf({
whitelist: [
'/applications'
]
}));
app.use(express.logger({stream:{
write: function(msg, encoding) {
logger.info(msg.trim());
@ -20,7 +25,6 @@ app.use(express.logger({stream:{
}}));
app.use(express.compress());
app.use(express.bodyParser());
app.use(express.csrf());
app.use(express.static(path.join(__dirname, 'static')));
app.use(flash());

Просмотреть файл

@ -1,3 +1,4 @@
var errors = require('./lib/errors');
var express = require('express');
var _ = require('underscore');
@ -25,3 +26,57 @@ exports.session = function session (config) {
})
});
};
exports.csrf = function (options) {
options = options || {};
var value = options.value || defaultCsrfValue;
var list = options.whitelist;
return function (req, res, next) {
if (whitelisted(list, req.url))
return next();
var token = req.session._csrf || (req.session._csrf = uid(24));
if ('GET' === req.method || 'HEAD' === req.method)
return next();
var val = value(req);
if (val != token) {
// logger.debug("CSRF token failure");
return next(errors.Forbidden());
}
next();
};
};
function defaultCsrfValue (req) {
return (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['x-csrf-token']);
}
function whitelisted (list, input) {
var pattern;
for (var i = list.length; i--;) {
pattern = list[i];
if (RegExp('^' + list[i] + '$').test(input))
return true;
}
return false;
}
function uid (len) {
var buf = [];
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charlen = chars.length;
for (var i = 0; i < len; ++i) {
buf.push(chars[getRandomInt(0, charlen - 1)]);
}
return buf.join('');
};
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}