mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
1be43911b4
Set Prettier's "trailingComma" setting to "es5" GitOrigin-RevId: 9f14150511929a855b27467ad17be6ab262fe5d5
74 lines
2.2 KiB
JavaScript
74 lines
2.2 KiB
JavaScript
const Metrics = require('@overleaf/metrics')
|
|
const logger = require('logger-sharelatex')
|
|
|
|
function computeValidationToken(req) {
|
|
// this should be a deterministic function of the client-side sessionID,
|
|
// prepended with a version number in case we want to change it later
|
|
return 'v1:' + req.sessionID.slice(-4)
|
|
}
|
|
|
|
function checkValidationToken(req) {
|
|
if (req.session) {
|
|
const sessionToken = req.session.validationToken
|
|
if (sessionToken) {
|
|
const clientToken = computeValidationToken(req)
|
|
// Reject invalid sessions. If you change the method for computing the
|
|
// token (above) then you need to either check or ignore previous
|
|
// versions of the token.
|
|
if (sessionToken === clientToken) {
|
|
Metrics.inc('security.session', 1, { status: 'ok' })
|
|
return true
|
|
} else {
|
|
logger.error(
|
|
{
|
|
sessionToken: sessionToken,
|
|
clientToken: clientToken,
|
|
},
|
|
'session token validation failed'
|
|
)
|
|
Metrics.inc('security.session', 1, { status: 'error' })
|
|
return false
|
|
}
|
|
} else {
|
|
Metrics.inc('security.session', 1, { status: 'missing' })
|
|
}
|
|
}
|
|
return true // fallback to allowing session
|
|
}
|
|
|
|
module.exports = {
|
|
enableValidationToken(sessionStore) {
|
|
// generate an identifier from the sessionID for every new session
|
|
const originalGenerate = sessionStore.generate
|
|
sessionStore.generate = function (req) {
|
|
originalGenerate(req)
|
|
// add the validation token as a property that cannot be overwritten
|
|
Object.defineProperty(req.session, 'validationToken', {
|
|
value: computeValidationToken(req),
|
|
enumerable: true,
|
|
writable: false,
|
|
})
|
|
Metrics.inc('security.session', 1, { status: 'new' })
|
|
}
|
|
},
|
|
|
|
validationMiddleware(req, res, next) {
|
|
if (!req.session.noSessionCallback) {
|
|
if (!checkValidationToken(req)) {
|
|
// the session must exist for it to fail validation
|
|
return req.session.destroy(() => {
|
|
return next(new Error('invalid session'))
|
|
})
|
|
}
|
|
}
|
|
next()
|
|
},
|
|
|
|
hasValidationToken(req) {
|
|
if (req && req.session && req.session.validationToken) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
},
|
|
}
|