session
session copied to clipboard
Regenerated session is re-saved even if not modified since save
PR #849 attempted to fix resaving an already-saved new session at the end of the request, but there's one corner case it missed. If session.regenerate() has been called before session.save(), then the request is still saved again at the end of the request.
This can actually lead to a race condition: if another request modifies the session after session.save() but before the end of the first request, then those modifications get overwritten when the first request ends. (And yes, this can happen in real world...)
How to reproduce: This code prints "saving" twice for one request (also verified by adding logging inside express-session)
const MemoryStore = require('express-session/session/memory')
const _set = MemoryStore.prototype.set
MemoryStore.prototype.set = function set() {
console.log('saving')
_set.apply(this, arguments)
}
const express = require('express')
const session = require('express-session')
const app = express()
app.use(session({
secret: 'cat',
resave: false,
saveUninitialized: false
}))
app.get('/', (req, res) => {
req.session.regenerate(() => {
req.session.value = 'foo'
req.session.save(() => {
res.send('hello')
})
})
})
app.listen(3000)
Outline of a possible fix:
- In index.js
wrapMethods, also wrapregenerate(same way asreload) - In the wrapped
savemethod, setoriginalId = this.id(so thatisSavedreturns true andisModifiedfalse, unless more modifications happen after saving)