Regenerate the session id after logging in or registering

This commit is contained in:
James Allen 2015-02-13 11:18:17 +00:00
parent f037c466cd
commit 8e13ded360
5 changed files with 69 additions and 54 deletions

View file

@ -6,6 +6,7 @@ Metrics = require('../../infrastructure/Metrics')
logger = require("logger-sharelatex") logger = require("logger-sharelatex")
querystring = require('querystring') querystring = require('querystring')
Url = require("url") Url = require("url")
uid = require "uid"
module.exports = AuthenticationController = module.exports = AuthenticationController =
login: (req, res, next = (error) ->) -> login: (req, res, next = (error) ->) ->
@ -25,8 +26,9 @@ module.exports = AuthenticationController =
if user? if user?
LoginRateLimiter.recordSuccessfulLogin email LoginRateLimiter.recordSuccessfulLogin email
AuthenticationController._recordSuccessfulLogin user._id AuthenticationController._recordSuccessfulLogin user._id
AuthenticationController._establishUserSession req, user, (error) -> AuthenticationController.establishUserSession req, user, (error) ->
return next(error) if error? return next(error) if error?
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"
res.send redir: redir res.send redir: redir
else else
@ -118,7 +120,7 @@ module.exports = AuthenticationController =
Metrics.inc "user.login.failed" Metrics.inc "user.login.failed"
callback() callback()
_establishUserSession: (req, user, callback = (error) ->) -> establishUserSession: (req, user, callback = (error) ->) ->
lightUser = lightUser =
_id: user._id _id: user._id
first_name: user.first_name first_name: user.first_name
@ -126,6 +128,12 @@ module.exports = AuthenticationController =
isAdmin: user.isAdmin isAdmin: user.isAdmin
email: user.email email: user.email
referal_id: user.referal_id referal_id: user.referal_id
# Regenerate the session to get a new sessionID (cookie value) to
# protect against session fixation attacks
oldSession = req.session
req.sessionStore.generate(req)
for key, value of oldSession
req.session[key] = value
req.session.user = lightUser req.session.user = lightUser
req.session.justLoggedIn = true callback()
req.session.save callback

View file

@ -89,10 +89,11 @@ module.exports =
next(err) next(err)
else else
metrics.inc "user.register.success" metrics.inc "user.register.success"
req.session.user = user
req.session.justRegistered = true
ReferalAllocator.allocate req.session.referal_id, user._id, req.session.referal_source, req.session.referal_medium ReferalAllocator.allocate req.session.referal_id, user._id, req.session.referal_source, req.session.referal_medium
SubscriptionDomainAllocator.autoAllocate(user) SubscriptionDomainAllocator.autoAllocate(user)
AuthenticationController.establishUserSession req, user, (error) ->
return callback(error) if error?
req.session.justRegistered = true
res.send res.send
redir:redir redir:redir
id:user._id.toString() id:user._id.toString()

View file

@ -39,6 +39,7 @@
"settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0",
"socket.io": "0.9.16", "socket.io": "0.9.16",
"translations-sharelatex": "git+https://github.com/sharelatex/translations-sharelatex.git#master", "translations-sharelatex": "git+https://github.com/sharelatex/translations-sharelatex.git#master",
"uid": "0.0.2",
"underscore": "1.6.0", "underscore": "1.6.0",
"underscore.string": "^3.0.2", "underscore.string": "^3.0.2",
"v8-profiler": "^5.2.3", "v8-profiler": "^5.2.3",

View file

@ -40,7 +40,7 @@ describe "AuthenticationController", ->
beforeEach -> beforeEach ->
@AuthenticationController._recordFailedLogin = sinon.stub() @AuthenticationController._recordFailedLogin = sinon.stub()
@AuthenticationController._recordSuccessfulLogin = sinon.stub() @AuthenticationController._recordSuccessfulLogin = sinon.stub()
@AuthenticationController._establishUserSession = sinon.stub().callsArg(2) @AuthenticationController.establishUserSession = sinon.stub().callsArg(2)
@req.body = @req.body =
email: @email email: @email
password: @password password: @password
@ -68,10 +68,13 @@ describe "AuthenticationController", ->
.should.equal true .should.equal true
it "should establish the user's session", -> it "should establish the user's session", ->
@AuthenticationController._establishUserSession @AuthenticationController.establishUserSession
.calledWith(@req, @user) .calledWith(@req, @user)
.should.equal true .should.equal true
it "should set res.session.justLoggedIn", ->
@req.session.justLoggedIn.should.equal true
it "should redirect the user to the specified location", -> it "should redirect the user to the specified location", ->
expect(@res.body).to.deep.equal redir: @redir expect(@res.body).to.deep.equal redir: @redir
@ -103,7 +106,7 @@ describe "AuthenticationController", ->
# type: 'error' # type: 'error'
it "should not establish a session", -> it "should not establish a session", ->
@AuthenticationController._establishUserSession.called.should.equal false @AuthenticationController.establishUserSession.called.should.equal false
it "should record a failed login", -> it "should record a failed login", ->
@AuthenticationController._recordFailedLogin.called.should.equal true @AuthenticationController._recordFailedLogin.called.should.equal true
@ -272,10 +275,7 @@ describe "AuthenticationController", ->
.calledWith(@req, {allow_auth_token: true}) .calledWith(@req, {allow_auth_token: true})
.should.equal true .should.equal true
describe "_redirectToLoginOrRegisterPage", -> describe "_redirectToLoginOrRegisterPage", ->
beforeEach -> beforeEach ->
@middleware = @AuthenticationController.requireLogin(@options = { load_from_db: false }) @middleware = @AuthenticationController.requireLogin(@options = { load_from_db: false })
@req.session = {} @req.session = {}
@ -312,9 +312,6 @@ describe "AuthenticationController", ->
@AuthenticationController._redirectToRegisterPage.calledWith(@req, @res).should.equal true @AuthenticationController._redirectToRegisterPage.calledWith(@req, @res).should.equal true
@AuthenticationController._redirectToLoginPage.calledWith(@req, @res).should.equal false @AuthenticationController._redirectToLoginPage.calledWith(@req, @res).should.equal false
describe "_redirectToRegisterPage", -> describe "_redirectToRegisterPage", ->
beforeEach -> beforeEach ->
@req.path = "/target/url" @req.path = "/target/url"
@ -371,11 +368,13 @@ describe "AuthenticationController", ->
it "should call the callback", -> it "should call the callback", ->
@callback.called.should.equal true @callback.called.should.equal true
describe "_establishUserSession", -> describe "establishUserSession", ->
beforeEach -> beforeEach ->
@req.session = @req.session =
save: sinon.stub().callsArg(0) save: sinon.stub().callsArg(0)
@AuthenticationController._establishUserSession @req, @user, @callback @req.sessionStore =
generate: sinon.stub()
@AuthenticationController.establishUserSession @req, @user, @callback
it "should set the session user to a basic version of the user", -> it "should set the session user to a basic version of the user", ->
@req.session.user._id.should.equal @user._id @req.session.user._id.should.equal @user._id
@ -385,6 +384,9 @@ describe "AuthenticationController", ->
@req.session.user.referal_id.should.equal @user.referal_id @req.session.user.referal_id.should.equal @user.referal_id
@req.session.user.isAdmin.should.equal @user.isAdmin @req.session.user.isAdmin.should.equal @user.isAdmin
it "should regenerate the session to protect against session fixation", ->
@req.sessionStore.generate.calledWith(@req).should.equal true
it "should return the callback", -> it "should return the callback", ->
@callback.called.should.equal true @callback.called.should.equal true

View file

@ -29,7 +29,8 @@ describe "UserController", ->
unsubscribe: sinon.stub().callsArgWith(1) unsubscribe: sinon.stub().callsArgWith(1)
@UserRegistrationHandler = @UserRegistrationHandler =
registerNewUser: sinon.stub() registerNewUser: sinon.stub()
@AuthenticationController = {} @AuthenticationController =
establishUserSession: sinon.stub().callsArg(2)
@AuthenticationManager = @AuthenticationManager =
authenticate: sinon.stub() authenticate: sinon.stub()
setUserPassword: sinon.stub() setUserPassword: sinon.stub()
@ -181,7 +182,9 @@ describe "UserController", ->
it "should put the user on the session and mark them as justRegistered", (done)-> it "should put the user on the session and mark them as justRegistered", (done)->
@UserRegistrationHandler.registerNewUser.callsArgWith(1, null, @user) @UserRegistrationHandler.registerNewUser.callsArgWith(1, null, @user)
@res.send = => @res.send = =>
assert.deepEqual @user, @req.session.user @AuthenticationController.establishUserSession
.calledWith(@req, @user)
.should.equal true
assert.equal @req.session.justRegistered, true assert.equal @req.session.justRegistered, true
done() done()
@UserController.register @req, @res @UserController.register @req, @res