Change csrf checking to a middleware function

This commit is contained in:
Evert Prants 2017-11-23 18:41:48 +02:00
parent 0d792817fe
commit b4b88a5657
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
1 changed files with 18 additions and 44 deletions

View File

@ -276,17 +276,22 @@ function cleanString (input) {
return output 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 // 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.session.user) return next()
if (!req.body.code) { if (!req.body.code) {
return formError(req, res, 'You need to enter the 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) let verified = await API.User.Login.totpCheck(req.session.user, req.body.code)
if (!verified) { if (!verified) {
return formError(req, res, 'Something went wrong! Try scanning the code again.') 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 // 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.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) { if (!req.body.password) {
return formError(req, res, 'Please enter your 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 // 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.user) return next()
if (req.session.totp_check === null) return res.redirect('/login') if (req.session.totp_check === null) return res.redirect('/login')
if (!req.body.code && !req.body.recovery) { if (!req.body.code && !req.body.recovery) {
return formError(req, res, 'You need to enter the 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 totpCheck = await API.User.Login.totpCheck(req.session.totp_check, req.body.code, req.body.recovery || false) let totpCheck = await API.User.Login.totpCheck(req.session.totp_check, req.body.code, req.body.recovery || false)
if (!totpCheck) { if (!totpCheck) {
return formError(req, res, 'Invalid code!') 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 // 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.session.user) return next()
if (!req.body.username || !req.body.password || req.body.username === '') { if (!req.body.username || !req.body.password || req.body.username === '') {
return res.redirect('/login') 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) let user = await API.User.get(req.body.username)
if (!user) return formError(req, res, 'Invalid username or password.') 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 // 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.session.user) return next()
if (!req.body.username || !req.body.display_name || !req.body.password || !req.body.email) { if (!req.body.username || !req.body.display_name || !req.body.password || !req.body.email) {
return formError(req, res, 'Please fill in all the fields.') 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 // Ban check
let banStatus = await API.User.getBanStatus(req.realIP, true) let banStatus = await API.User.getBanStatus(req.realIP, true)
if (banStatus.length) { if (banStatus.length) {
@ -483,13 +473,9 @@ router.post('/register', accountLimiter, wrap(async (req, res, next) => {
})) }))
// Change display name // 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.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) { if (!req.body.display_name) {
return formError(req, res, 'Display Name cannot be blank.') 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 // 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.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) { if (!req.body.password_old) {
return formError(req, res, 'Please enter your current password.') 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 // 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.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 user = await API.User.get(req.session.user)
let email = req.body.email let email = req.body.email
let newEmail = req.body.email_new let newEmail = req.body.email_new
@ -667,11 +645,7 @@ router.get('/news/compose', newsPrivilege, formKeep, (req, res) => {
res.render('news/composer') res.render('news/composer')
}) })
router.post('/news/compose', newsPrivilege, wrap(async (req, res) => { router.post('/news/compose', newsPrivilege, csrfValidation, wrap(async (req, res) => {
if (req.body.csrf !== req.session.csrf) {
return formError(req, res, 'Invalid session! Try reloading the page.')
}
if (!req.body.title || !req.body.content) { if (!req.body.title || !req.body.content) {
return formError(req, res, 'Required fields missing!') return formError(req, res, 'Required fields missing!')
} }