在我们的平均值(mysql express angularjs和node)应用程序中,我们已将node js版本从0.10.16升级到10.15.1。 csrf()令牌验证问题正在增加。
在http://hostname/auth/sign中 signin.pug
.content
form.login-form(action='/auth/signin', method='post', accept-charset='utf-8', novalidate='')
input(type='hidden', name='_csrf', value=token)
login form goes below
express.js
/**
* Module dependencies.
*/
var express = require('express.io'),
flash = require('connect-flash'),
config = require('./config'),
acl = require('connect-roles'),
csrf = express.csrf(),
sanitizer = require('sanitize-html'),
crypto = require('crypto'),
_ = require('underscore'),
winston = require('./winston'),
morgan = require('morgan');
module.exports = function (app, passport, rest, db) {
app.set('showStackError', true);
//Should be placed before express.static
app.use(express.compress({
filter: function (req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
//Setting the fav icon and static folder
app.use(express.favicon());
// app.use(express.static(config.root + '/public'));
app.use('/assets', express.static(config.root + '/public/assets'));
app.use('/js', express.static(config.root + '/public/js'));
app.use('/minjs', express.static(config.root + '/public/minjs'));
app.use('/resources', express.static(config.root + '/public/resources'));
// app.use('/views',express.static(config.root + '/public/views'));
//Don't use logger for test env
if (process.env.NODE_ENV !== 'test') {
app.use(express.logger('dev'));
}
app.use(morgan('combined', { stream: winston.stream }));
//Set views path, template engine and default layout
app.set('views', config.root + '/app/views');
app.set('view engine', 'jade');
//Enable jsonp
app.enable('jsonp callback');
app.configure(function () {
app.use(function noCachePlease(req, res, next) {
res.header('Cache-Control', 'no-store');
res.header('Content-Security-Policy', "frame-ancestors 'self'");
res.header('X-Frame-Options', 'DENY');
next();
});
//cookieParser should be above session
app.use(express.cookieParser('mc_secret'));
//bodyParser should be above methodOverride
app.use(express.json());
app.use(express.urlencoded());
//sanitize
app.use(function (req, res, next) {
if (req.body) {
_.each(req.body, function (value, key) {
if (!parseInt(value, 10) && value !== null) {
if (typeof value === 'string') {
value = value.replace(/>/gi, '>');
value = value.replace(/</gi, '<');
value = value.replace(/(©|"|&)/gi, '');
req.body[key] = sanitizer(value, {
allowedTags: []
});
}
}
});
}
return next();
});
app.use(express.methodOverride());
var session = require('express-session');
var SessionStore = require('express-mysql-session')(session);
var options = {
host: config.db.local.options.host,
port: config.db.local.options.port,
user: config.db.local.username,
password: config.db.local.password,
database: config.db.local.name
};
var sessionStore = new SessionStore(options);
var sessionOptions = {
key: 'mc_cookies',
secret: 'mc_secret',
store: sessionStore,
resave: false,
saveUninitialized: false
};
//production HTTPS
//AWS Issue: Can't set a secure cookie on ELB
// It might be because the traffic hitting your instances is not SSL
// It is decrypted by then
if (process.env.MC_ENV === 'local') {
app.enable('trust proxy');
sessionOptions.proxy = true;
sessionOptions.cookie = {
httpOnly: true,
secure: true
};
/*
app.use(function (req, res, next) {
if (!req.secure) {
return res.redirect('https://' + req.host + req.url);
}
next();
});
*/
}
app.use(function (req, res, next) {
next();
});
app.use(session(sessionOptions));
// app.use(express.session(sessionOptions));
/* Allow only app to post/get requests */
var conditionalCSRF = function (req, res, next) {
//('conditionalCSRF: ', req.method, req.url);
//OAuth2 URLs
var whitelist = [
'/oauth2/authorize/decision',
'/oauth2/token',
'/oauth2/signin',
];
if (process.env.MC_ENV === 'local') {
req.csrfNeeded = true;
if (whitelist.indexOf(req.url) !== -1 && req.method === 'POST') {
req.csrfNeeded = false;
next();
} else {
console.log('csrf(): ', req.method, req.url);
csrf(req, res, next);
}
}
else
next();
};
app.use(conditionalCSRF);
//since the csrf does not block GET requests let's ban them manually
function createToken(salt, secret) {
return salt + crypto
.createHash('sha1')
.update(salt + secret)
.digest('base64');
}
function checkToken(token, secret) {
if ('string' !== typeof token) return false;
return token === createToken(token.slice(0, 10), secret);
}
app.use(function (req, res, next) {
var isAllowed = true;
//console.log('req.csrfNeeded: ', req.csrfNeeded);
if (req.csrfNeeded) {
res.cookie('XSRF-TOKEN', req.csrfToken());
res.locals.token = req.csrfToken();
if ((req.method === 'POST' || req.method === 'GET') &&
req.url.indexOf('/api/v2/') !== -1) {
var secret = req.session._csrfSecret;
var val = req.headers['x-xsrf-token'];
isAllowed = checkToken(val, secret);
}
next();
}
//console.log('csrfNeeded check: ', req.method, req.url, isAllowed);
if (!isAllowed) {
res.status(403);
res.render('403.pug', {error: '403: Forbidden'});
} else {
next();
}
});
//connect flash for flash messages
app.use(flash());
//use passport session
app.use(passport.initialize());
app.use(passport.session());
app.use(require('../app/lib/middleware/rest')(rest));
app.use(require('../app/lib/middleware/db')(db));
//routes should be at the last
app.use(app.router);
//Acl section
app.use(acl);
需要为应用程序启用csrf(),我尝试通过添加新的软件包csruf()并删除它,因为它显示了无效的令牌并且没有修复它。