It's possible to do a session fixation attack against a site using passport where you are able to obtain the session ID of a browser session pre-login, allow the user to login, and then use that session ID elsewhere.
Now, this is a somewhat minor issue since assuming there are no other security issues, you would assumingly need physical access to the machine.
Now, with that said, it seems worthwhile to address this issue. The best way to fix this is to simply regenerate the session after the user authenticates, destroying the old one.
However, because of my lack of knowledge on how all the different passport modules interact, I'm not sure where to implement this fix. My initial thought is in req.login.
I don't think this is an issue directly with Passport. As you note, the problem here would be exposing your session ID, which is more related to transport security and operational security.
In any case, Passport doesn't assign session IDs. If you want to regenerate a session upon login, I think that is wise and advisable, but there may be application-level reasons not to do that. I'd be fine with adding an option to do that to req.logIn. It's also entirely possible for applications to do this themselves in their login route handler.
I see that passport takes great care to isolate it's own session data as much as possible to not disturb other uses of the session, which seems to be good. I'll come back to this in the coming weeks and try one of the things you suggested and maybe submit a pull request.
Application use case for not regenerating session IDs:
- anonymous user begins adding items to a shopping cart
- user proceeds to check out
- user logs in, in order to select previously registered shipping address
In this case, you would not want to lose the existing session, because you don't want to lose the cart. An application _may_ generate a new session ID, assuming it can also migrate existing cart items to the new session. This is clearly out of scope of authentication.
What you are describing is not a session fixation attack. Assuming an attacker had the ability to observe session IDs being issued by an application, they can also easily observe any newly regenerated session IDs.
Closing.
For anyone stumbling across this trying to avoid a session fixation attack by regenerating session IDs on login, and wondering how to not break passport in the process, this Stack Overflow question was helpful for me: http://stackoverflow.com/questions/22209354/creating-a-new-session-after-authentication-with-passport
@jaredhanson
What you are describing is not a session fixation attack. Assuming an attacker had the ability to observe session IDs being issued by an application, they can also easily observe any newly regenerated session IDs.
The lack of session ID regeneration after login is the base of a session fixation attack.
The attack works by inducing a user to use a sessionID which you are aware of. Note that this does not mean that you can observe all session IDs. Abstract techniques to launch such an attack can be found at @https://www.owasp.org/index.php/Session_fixation .
A simpler but also rarer scenario is the following:
Attacker has temporary physical access to victims browser. The attacker captures the session ID, walks away and waits for the victim to authenticate himself. Provided that the unauthenticated session has not expired on the server-side and that the cookie was nor removed from the browser (e.g. by closing the browser), the attacker will be able to high-jack the session as soon as the victim logs in.
That was a very simplistic example and I acknowledge that if the attacker has physical access, the security of the session is the least of our concerns.
I'd be fine with adding an option to do that to req.logIn.
I believe that this would be a great addition.
Application use case for not regenerating session IDs:
- anonymous user begins adding items to a shopping cart
- user proceeds to check out
- user logs in, in order to select previously registered shipping address
Ideally, just the session ID would be regenerated without loosing all the data that were imported in the session object. I've been trying to customize authenticate() as mentioned at @http://stackoverflow.com/questions/22209354/creating-a-new-session-after-authentication-with-passport but I had little lack transferring the session data.
EDIT: Requested for an easy way to do it at https://github.com/expressjs/session/issues/425 since I believe that whether using passport or not, express-session should provide that functionality.
However, I believe that Passport should add this option in the logIn() (or maybe authenticate()???) function, as soon as express-session provides it.
+1
I think this is an issue.
More detail on session fixation in this research paper: http://www.acrossecurity.com/papers/session_fixation.pdf
Looks like there are many attack vectors besides directly compromising the browser and OWASP states "The session ID regeneration is mandatory to prevent session fixation attacks" (https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Renew_the_Session_ID_After_Any_Privilege_Level_Change)
So if countermeasures can't be implemented directly as part of a "secure by default" strategy, I think they should at least be prominently advised in the documentation. Maybe it's also possible to issue console warnings if the session id is not being regenerated.
The links posted by @eug48 have been moved to a github repo. It is correct that OWASP states this behavior is a vulnerability. A great explanation is available here
I'm hoping that passport will be updated to keep up with current best practices.
@jaredhanson any thoughts on this now that a few years have passed?
@jaredhanson - Any thoughts on re-addressing this given that OWASP treats this behavior as a vulnerability?
+1 馃檹
Most helpful comment
For anyone stumbling across this trying to avoid a session fixation attack by regenerating session IDs on login, and wondering how to not break passport in the process, this Stack Overflow question was helpful for me: http://stackoverflow.com/questions/22209354/creating-a-new-session-after-authentication-with-passport