mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Regenerate session on login, protect against session-fixation attack.
This commit is contained in:
parent
bb71433727
commit
dde5b7b830
2 changed files with 31 additions and 4 deletions
|
@ -39,7 +39,19 @@ module.exports = AuthenticationController =
|
||||||
return next(err)
|
return next(err)
|
||||||
if user # `user` is either a user object or false
|
if user # `user` is either a user object or false
|
||||||
req.login user, (err) ->
|
req.login user, (err) ->
|
||||||
res.json {redir: req._redir}
|
# Regenerate the session to get a new sessionID (cookie value) to
|
||||||
|
# protect against session fixation attacks
|
||||||
|
oldSession = req.session
|
||||||
|
req.session.destroy()
|
||||||
|
req.sessionStore.generate(req)
|
||||||
|
for key, value of oldSession
|
||||||
|
req.session[key] = value
|
||||||
|
req.session.save (err) ->
|
||||||
|
if err?
|
||||||
|
logger.err {user_id: user._id}, "error saving regenerated session after login"
|
||||||
|
return next(err)
|
||||||
|
UserSessionsManager.trackSession(user, req.sessionID, () ->)
|
||||||
|
res.json {redir: req._redir}
|
||||||
else
|
else
|
||||||
res.json message: info
|
res.json message: info
|
||||||
)(req, res, next)
|
)(req, res, next)
|
||||||
|
@ -60,9 +72,8 @@ module.exports = AuthenticationController =
|
||||||
LoginRateLimiter.recordSuccessfulLogin(email)
|
LoginRateLimiter.recordSuccessfulLogin(email)
|
||||||
AuthenticationController._recordSuccessfulLogin(user._id)
|
AuthenticationController._recordSuccessfulLogin(user._id)
|
||||||
Analytics.recordEvent(user._id, "user-logged-in")
|
Analytics.recordEvent(user._id, "user-logged-in")
|
||||||
UserSessionsManager.trackSession(user, req.sessionID, () ->)
|
|
||||||
req.session.justLoggedIn = true
|
|
||||||
logger.log email: email, user_id: user._id.toString(), "successful log in"
|
logger.log email: email, user_id: user._id.toString(), "successful log in"
|
||||||
|
req.session.justLoggedIn = true
|
||||||
# capture the request ip for use when creating the session
|
# capture the request ip for use when creating the session
|
||||||
user._login_req_ip = req.ip
|
user._login_req_ip = req.ip
|
||||||
req._redir = redir
|
req._redir = redir
|
||||||
|
|
|
@ -20,7 +20,7 @@ describe "AuthenticationController", ->
|
||||||
"../Security/LoginRateLimiter": @LoginRateLimiter = { processLoginRequest:sinon.stub(), recordSuccessfulLogin:sinon.stub() }
|
"../Security/LoginRateLimiter": @LoginRateLimiter = { processLoginRequest:sinon.stub(), recordSuccessfulLogin:sinon.stub() }
|
||||||
"../User/UserHandler": @UserHandler = {setupLoginData:sinon.stub()}
|
"../User/UserHandler": @UserHandler = {setupLoginData:sinon.stub()}
|
||||||
"../Analytics/AnalyticsManager": @AnalyticsManager = { recordEvent: sinon.stub() }
|
"../Analytics/AnalyticsManager": @AnalyticsManager = { recordEvent: sinon.stub() }
|
||||||
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
|
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), err: sinon.stub() }
|
||||||
"settings-sharelatex": {}
|
"settings-sharelatex": {}
|
||||||
"passport": @passport =
|
"passport": @passport =
|
||||||
authenticate: sinon.stub().returns(sinon.stub())
|
authenticate: sinon.stub().returns(sinon.stub())
|
||||||
|
@ -50,6 +50,10 @@ describe "AuthenticationController", ->
|
||||||
@info = null
|
@info = null
|
||||||
@req.login = sinon.stub().callsArgWith(1, null)
|
@req.login = sinon.stub().callsArgWith(1, null)
|
||||||
@res.json = sinon.stub()
|
@res.json = sinon.stub()
|
||||||
|
@req.session = @session = {test: 'test'}
|
||||||
|
@req.session.destroy = sinon.stub()
|
||||||
|
@req.session.save = sinon.stub().callsArgWith(0, null)
|
||||||
|
@req.sessionStore = {generate: sinon.stub()}
|
||||||
@passport.authenticate.callsArgWith(1, null, @user, @info)
|
@passport.authenticate.callsArgWith(1, null, @user, @info)
|
||||||
|
|
||||||
it 'should call passport.authenticate', () ->
|
it 'should call passport.authenticate', () ->
|
||||||
|
@ -85,6 +89,18 @@ describe "AuthenticationController", ->
|
||||||
@res.json.callCount.should.equal 1
|
@res.json.callCount.should.equal 1
|
||||||
@res.json.calledWith({redir: @req._redir}).should.equal true
|
@res.json.calledWith({redir: @req._redir}).should.equal true
|
||||||
|
|
||||||
|
describe 'when session.save produces an error', () ->
|
||||||
|
beforeEach ->
|
||||||
|
@req.session.save = sinon.stub().callsArgWith(0, new Error('woops'))
|
||||||
|
|
||||||
|
it 'should return next with an error', () ->
|
||||||
|
@AuthenticationController.passportLogin @req, @res, @next
|
||||||
|
@next.calledWith(@err).should.equal true
|
||||||
|
|
||||||
|
it 'should not return json', () ->
|
||||||
|
@AuthenticationController.passportLogin @req, @res, @next
|
||||||
|
@res.json.callCount.should.equal 0
|
||||||
|
|
||||||
describe 'when authenticate does not produce a user', ->
|
describe 'when authenticate does not produce a user', ->
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
|
Loading…
Reference in a new issue