From b4b88a5657c484cca0ccdb00a9af372d4557030a Mon Sep 17 00:00:00 2001 From: Evert Date: Thu, 23 Nov 2017 18:41:48 +0200 Subject: [PATCH] Change csrf checking to a middleware function --- server/routes/index.js | 62 ++++++++++++------------------------------ 1 file changed, 18 insertions(+), 44 deletions(-) diff --git a/server/routes/index.js b/server/routes/index.js index f9cb2a4..75d156e 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -276,17 +276,22 @@ function cleanString (input) { return output } +// Make sure CSRF tokens are present and valid in every form +function csrfValidation (req, res, next) { + if (req.body.csrf !== req.session.csrf) { + return formError(req, res, 'Invalid session! Try reloading the page.') + } + + next() +} + // Enabling 2fa -router.post('/user/two-factor', wrap(async (req, res, next) => { +router.post('/user/two-factor', csrfValidation, wrap(async (req, res, next) => { if (!req.session.user) return next() if (!req.body.code) { return formError(req, res, 'You need to enter the code.') } - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - let verified = await API.User.Login.totpCheck(req.session.user, req.body.code) if (!verified) { return formError(req, res, 'Something went wrong! Try scanning the code again.') @@ -296,11 +301,8 @@ router.post('/user/two-factor', wrap(async (req, res, next) => { })) // Disabling 2fa -router.post('/user/two-factor/disable', wrap(async (req, res, next) => { +router.post('/user/two-factor/disable', csrfValidation, wrap(async (req, res, next) => { if (!req.session.user) return next() - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } if (!req.body.password) { return formError(req, res, 'Please enter your password.') @@ -315,17 +317,13 @@ router.post('/user/two-factor/disable', wrap(async (req, res, next) => { })) // Verify 2FA for login -router.post('/login/verify', wrap(async (req, res, next) => { +router.post('/login/verify', csrfValidation, wrap(async (req, res, next) => { if (req.session.user) return next() if (req.session.totp_check === null) return res.redirect('/login') if (!req.body.code && !req.body.recovery) { return formError(req, res, 'You need to enter the code.') } - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - let totpCheck = await API.User.Login.totpCheck(req.session.totp_check, req.body.code, req.body.recovery || false) if (!totpCheck) { return formError(req, res, 'Invalid code!') @@ -339,16 +337,12 @@ router.post('/login/verify', wrap(async (req, res, next) => { })) // Log the user in. Limited resource -router.post('/login', accountLimiter, wrap(async (req, res, next) => { +router.post('/login', accountLimiter, csrfValidation, wrap(async (req, res, next) => { if (req.session.user) return next() if (!req.body.username || !req.body.password || req.body.username === '') { return res.redirect('/login') } - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - let user = await API.User.get(req.body.username) if (!user) return formError(req, res, 'Invalid username or password.') @@ -390,16 +384,12 @@ router.post('/login', accountLimiter, wrap(async (req, res, next) => { })) // Protected & Limited resource: Account registration -router.post('/register', accountLimiter, wrap(async (req, res, next) => { +router.post('/register', accountLimiter, csrfValidation, wrap(async (req, res, next) => { if (req.session.user) return next() if (!req.body.username || !req.body.display_name || !req.body.password || !req.body.email) { return formError(req, res, 'Please fill in all the fields.') } - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - // Ban check let banStatus = await API.User.getBanStatus(req.realIP, true) if (banStatus.length) { @@ -483,13 +473,9 @@ router.post('/register', accountLimiter, wrap(async (req, res, next) => { })) // Change display name -router.post('/user/manage', wrap(async (req, res, next) => { +router.post('/user/manage', csrfValidation, wrap(async (req, res, next) => { if (!req.session.user) return next() - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - if (!req.body.display_name) { return formError(req, res, 'Display Name cannot be blank.') } @@ -521,13 +507,9 @@ router.post('/user/manage', wrap(async (req, res, next) => { })) // Change user password -router.post('/user/manage/password', accountLimiter, wrap(async (req, res, next) => { +router.post('/user/manage/password', accountLimiter, csrfValidation, wrap(async (req, res, next) => { if (!req.session.user) return next() - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - if (!req.body.password_old) { return formError(req, res, 'Please enter your current password.') } @@ -572,13 +554,9 @@ router.post('/user/manage/password', accountLimiter, wrap(async (req, res, next) })) // Change email address -router.post('/user/manage/email', accountLimiter, wrap(async (req, res, next) => { +router.post('/user/manage/email', accountLimiter, csrfValidation, wrap(async (req, res, next) => { if (!req.session.user) return next() - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - let user = await API.User.get(req.session.user) let email = req.body.email let newEmail = req.body.email_new @@ -667,11 +645,7 @@ router.get('/news/compose', newsPrivilege, formKeep, (req, res) => { res.render('news/composer') }) -router.post('/news/compose', newsPrivilege, wrap(async (req, res) => { - if (req.body.csrf !== req.session.csrf) { - return formError(req, res, 'Invalid session! Try reloading the page.') - } - +router.post('/news/compose', newsPrivilege, csrfValidation, wrap(async (req, res) => { if (!req.body.title || !req.body.content) { return formError(req, res, 'Required fields missing!') }