Skip Menu |

This queue is for tickets about the Catalyst-Plugin-Session CPAN distribution.

Report information
The Basics
Id: 46318
Status: resolved
Priority: 0/
Queue: Catalyst-Plugin-Session

People
Owner: bobtfish [...] bobtfish.net
Requestors: kmx [...] volny.cz
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Session fixation vulnerability
Date: Sat, 23 May 2009 23:49:28 +0200
To: bug-Catalyst-Plugin-Authentication [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
I guess that the current implementation of Catalyst-Plugin-Authentication (or maybe Catalyst-Plugin-Session) does not prevent Session fixation attack because it does not force generation of new sessionid (=cookie) during authenticate() and logout(). It could be handled by some additional code in the cat application: [LOGIN] if ($c->authenticate( { username => $user, password => $pass } )) { $c->create_session_id(); ... } ... note: it probably is also not optimal as create_session_id() is declared to be an internal method of "Catalyst::Plugin::Session" (it probably means something like "could be changed without notice") [LOGOUT] sub logout :Global :Args(0) { my ( $self, $c ) = @_; if ($c->user_exists) { $c->delete_session("logout"); $c->logout(); ... } ... However in my opinion the framework itself should prevent session fixation attack. My proposal is to force sessionid change (new id) during both discussed calls: - authenticate() - logout() The problem might occur with applications that first uses the session in "anonymous phase" (e.g. user is adding goods into cart before login), then let user log in and want to keep his/her session data for "authenticated phase" (to finish the order and pay for it). To prevent session fixation in this scenarion it is necessary to give the user a new sessionid and make a copy of session data. Patching logout() method seems to be quite straightforward - something like this: --- Authentication.pm --- sub logout { my $c = shift; + if ($c->can('session') and $c->config->{'Plugin::Authentication'}{'use_session'} ) { + $c->delete_session("logout") + } $c->user(undef); --- Little bit tricky is authenticate() as we have to handle two modes: 1) we want the complete reset and clean new session 2) we want just to chage sessionid but keep session data I would propose a new authenticate() parameter "keepsessiondata" that will indicate the mode. What I have no idea how to do is copying the session data in case we want to keep them. The interface of Catalyst::Plugin::Session does not help much - I am afraid that it might require to implement some additional method for "cloning/copying" existing session data. Any idea? -- kmx
Hi. After we discussed this, I thought that the correct approach is probably to write some failing tests for either -Authentication or -Session I wrote a trivial test for the session code already: http://dev.catalyst.perl.org/svnweb/Catalyst/revision?rev=10246 I'll try to write some more tests for this issue - but I think that this shows it isn't present for the simple case, do you agree? Have you actually observed this bug for real? And if so, could you provide some sets of HTTP request and response headers which demonstrate? I'm moving this bug into the queue for the Plugin::Session dist for the moment, but I may move it back if that proves appropriate later ;)
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Sun, 24 May 2009 12:21:18 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Hi, here comes my "real story" with Catalyst application: 1) start new browser (=without any cookie for CatApp) 2) go to: http://localhost/publicaction - anonymous access at this moment - the action saves some session variable => it causes new sessionid (cookie) to be generrated - in Dump($c->session) I see: {anonymous1}= "test"; - it generates sessionid for example "sess111111111111" 3) go to: http://localhost/showsessionvars - still anonymous - if I print in this action $c->session has I see: {anonymous1}= "test1"; - sessionid = "sess111111111111" 4) go to: http://localhost/login - at some point it calls $c->authenticate( { username => $user, password => $pass } ) - but it DOES NOT force my browser to change sessionid cookie 5) go to: http://localhost/showsessionvars - now I am authenticated - in Dump($c->session) I see: {anonymous1}= "test"; - I have still the same sessionid = "sess111111111111" 6) go to: http://localhost/authaction - authenticated access at this moment - the action saves some session variable, for example $c->session->{auth1}= "test2"; - as expected I have still the same sessionid = "sess111111111111" 4) access to: http://localhost/logout - at some point it calls $c->logout() - but it DOES NOT force my browser to change sessionid cookie 6) access to: http://localhost/showsessionvars - now I am anonymous again - in Dump($c->session) I see: {anonymous1}= "test1"; {auth1}= "test2"; (session vars were NOT CLEARED) - I have still the same sessionid = "sess111111111111" I see generally 2 problems: 1) session ID should definitely change during authenticate() and logout() 2) it is a question whether also to clear session data during authenticate() and logout() - or at least add a new parameter to these functions (e.g. "keepsessiondata") that allows a developer to decide whether he needs to keep session data or not In Catalyst-Plugin-Session there should be tests at least for: 1) sessionid change during authenticate() 2) sessionid change during logout() 3) if I come with completely unknown cookie CatApp should not accept it and generate complete new one (this already works fine) Your test added to rev=10246 tests the case 3) - and as I have said it works with current release well. The test for persistence of session data during authenticate() and logout() should probably go to Catalyst-Plugin-Authentication. -- kmx
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Sun, 24 May 2009 12:39:01 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Here is an example of attack scenario: 1) Let us have an e-shop CatApp with some anonymous part (filling your cart with goods) and authenticated part (order, payment) 2) I will go to e-shop and browse just the anonymous part - tha catApp gives me sessionid "sess11111" 3) I will try to play on you (your browser) for example http://en.wikipedia.org/wiki/Cross-site_cooking and insert sessionid cookie for CatApp into your browser (value "sess11111") - for example you visit my malicious web forum where I put some ugly Javascript that tries to abuse some vulnerability in you browser to insert the above mentioned cookie 4) now you will go to the same e-shop as I in point 2) - you pick up some goods and login (to pay for it) 5) after your login you still have sessionid "sess11111" that is also known to me => I can enter your session and do whatever the application allows me -- kmx
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Sun, 24 May 2009 11:53:36 +0100
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: Tomas Doran <bobtfish [...] bobtfish.net>
kmx via RT wrote: Show quoted text
> Here is an example of attack scenario:
Thanks for the extensive clarification :) I mostly worked through that in my head myself before I got to sleep last night, but having it written down is like that is extremely clear. As you noted, -Session isn't vulnerable to the simple case, but -Authentication should force session ID change as suggested. I'll move the ticket back into that queue then ;) Cheers t0m
A session fixation vulnerability is specifically the ability to force a specific session id, and then attack the user's account by accessing the site using the forced session id. This problem does not exist as far as I can tell and the test provided demonstrates that this does not work. The other attack scenarios provided demonstrate access to the legitimate users machine in some way - (cross site scripting, etc) after a session id has been provided. There is no way to prevent that attack. If session id is changed at login / logout, it simply moves the point at which cross-site scripting attack needs to be done to sometime between the login and logout. The auth system already de-authenticates the session when logout takes place so a session post logout is not useful to an attacker. It is not appropriate for the Catalyst Auth plugin to wipe the session variables that it did not put there. Also - the session plugin already supports a delete_session() method which you can place where you like to destroy any session data that may exist. IF you desire the 'kill the session' or 'migrate the session' options you can delete the sessions prior to the authenticate call and after logout and you will get the same functionality.
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Sun, 24 May 2009 18:39:40 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Show quoted text
>The other attack scenarios provided demonstrate access to the legitimate >users machine in some way - (cross site scripting, etc) after a session >id has been provided.
No, I am absolutely sure that the second scenario simply is session fixation attack. See: http://en.wikipedia.org/wiki/Session_fixation#Attack_using_server_generated_SID or see OWASP: http://www.owasp.org/index.php/Session_Fixation Show quoted text
>There is no way to prevent that attack. If session id is changed at >login / logout, it simply moves the point at which cross-site scripting >attack needs to be done to sometime between the login and logout.
It is not true as the attacker is not able to get the new sessionid I will get after authenticate(). The original problem was that in described scenario the victim is using sessionid value that the server originally generated for attacker that is able to insert cookie into my browser - however this ability is not enough for entering authenticated session if authenticate() will change the sessionid. Show quoted text
>IF you desire the 'kill the session' or 'migrate the session' options >you can delete the sessions prior to the authenticate call and after >logout and you will get the same functionality.
OK, I generally agree. However in my opinion switching sessionid (and keeping the data) during authenticate() is something that should be recommended as "catalyst secure coding best-practice" and it would be wise to use in 99% cases (it prevents session fixation and doesn't not harm anything - when keeping the session data). If it is good for nearly everybody why not to do it framework? The other thing is that with current C::P::Session it is not so easy to implement sessionid switch on my own as there is not any handy method for that in C::P::Session. It was just idea - if you still think that "this problem does not exist", leave it. -- kmx
On Sun May 24 12:40:15 2009, kmx@volny.cz wrote: Show quoted text
> No, I am absolutely sure that the second scenario simply is session > fixation attack. See: >
http://en.wikipedia.org/wiki/Session_fixation#Attack_using_server_generated_SID Show quoted text
I have read this. The fact is that if the attacker can override the SID, then no session process is secure. Let's examine the process... since Catalyst will not accept an externally generated session that does not exist already, the only option available is for Malory to access site, generate a session, and then inject that into Alice's cookie somehow. First off, since a session is not created unless there is something to store in it, the only time this will work is if Malory already logs in, or the site stores session information prior to login. Regardless, if Malory has access to the cookies on the Alice's machine, then Malory could obtain the regenerated session ID post login as well. Since logout removes authenticated status from the session already, the only attack possible is if the following things happen: a) Malory generates a legitimate session and gets it into Alice's cookies b) Alice logs in to site to perform some action c) Malory figures out when Alice is logged in and attacks before d) Alice logs out. If Alice logs out a few minutes after she logs in, it's unlikely Malory can perform any illicit activity. If Alice does not, Malory can likely use cross-site-scripting to obtain Alice's SID cookie anyway. Adding a session id change after login simply time-shifts the required cross-site-scripting attack. The fix proposed gives a false sense of security in that respect. Furthermore, this is a session problem, not an Authentication plugin problem, so the fix, if there is one, should be within the session plugin. There is no guarantee the user is using only the Authentication plugin for user storage, and there is no guarantee that the session is not being used to store sensitive data without a user being authenticated. Finally, the Authentication plugin uses session for user persistence only by default. There is no hard tie to the session plugin and thus incorporating in the Auth module a hard-tie to the session plugin to kill this session error is inappropriate. There are too many variations. If this is a concern, I think the appropriate action is to note the possibility in the session documentation and how to handle it in your login / logout code... but again that doesn't solve the above issue. The other option is to create a Session::State module that rotates the session id every X number of requests. This would be much more effective in preventing any form of attack on the session id. Let me be clear, I am supportive of a method to change the session id and retain the information stored in the session, but I do not believe this should be done automatically. If it's created as a rotating plugin, then the developer, if concerned about this, can use it and have faith that it will actually solve the problem. Jay
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Sun, 24 May 2009 22:34:10 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Hi, Show quoted text
>... the only attack possible is if the following things happen: > >a) Malory generates a legitimate session and gets it into Alice's cookies >b) Alice logs in to site to perform some action >c) Malory figures out when Alice is logged in and attacks before >d) Alice logs out. >
Agree: - that is pretty similar to my example with e-shop (see my post above) - it perfectly fits OWASP and Wikipedia definition - you might not agree but it simply is session fixation To sum up: CatApp using pure "authenticate()" without any additional session "magic" is vulnerable to session fixation. I am saying "magic" as there is no ready-to-use method like $c->change_sessionid_while_keeping_session_data(). Show quoted text
>If Alice logs out a few minutes after she logs in, it's unlikely Malory >can perform any illicit activity. If Alice does not, Malory can likely >use cross-site-scripting to obtain Alice's SID cookie anyway. > >Adding a session id change after login simply time-shifts the required >cross-site-scripting attack. The fix proposed gives a false sense of >security in that respect.
The described session fixation does not require any XSS in CatApp. Steeling the cookie via XSS is a sort of session hijacking attack and it is slightly different issue. I am not saying that my proposal is the only optimal solution, I am just saying the session fixation issue is there and I am objecting your opinion "this problem does not exists". <off topic> BTW: stealing the session cookie by Javascript (e.g. the mentioned XSS) could be made significantly harder if the cookie has HTTPOnly flag set - more info see for example http://www.owasp.org/index.php/HTTPOnly However Catalyst::Plugin::Session::State::Cookie does not play with this flag. I know that it does not concern this module. </off topic> Show quoted text
>Furthermore, this is a session problem, not an Authentication plugin >problem, so the fix, if there is one, should be within the session >plugin. There is no guarantee the user is using only the Authentication >plugin for user storage, and there is no guarantee that the session is >not being used to store sensitive data without a user being >authenticated. Finally, the Authentication plugin uses session for user >persistence only by default. There is no hard tie to the session plugin >and thus incorporating in the Auth module a hard-tie to the session >plugin to kill this session error is inappropriate.
Agree but be aware of the fact that many security vulnerabilities are quite complex and goes through many parts of the application/system. These vulnerabilities does not care how it is organised inside the Catalyst. Show quoted text
>There are too many variations. If this is a concern, I think the >appropriate action is to note the possibility in the session >documentation and how to handle it in your login / logout code... but >again that doesn't solve the above issue.
OK - let us say you will put in doc 2 possibilities: 1) use just "authenticate()" and be vulnerable to session fixation 2) use "authenticate()" + "something()" + "maybesomethingelse()" and be proof against session fixation Who will be interested in option 1) ? (I cannot think of any side effects when changing just sessiocookie name) Show quoted text
>Let me be clear, I am supportive of a method to change the session id >and retain the information stored in the session, but I do not believe >this should be done automatically.
I understand. I am not insisting on my proposal. It was just idea. In the end it is your package :) -- kmx
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Wed, 03 Jun 2009 10:20:36 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Hi, to sum up we have two scenarios (in fact not so different) SCENARIO 1: 1) the hacker takes any random sessionid value 2) hacker inserts (somehow) this values into a cookie in victim's browser 3) after the victim logs into WebApp the hacker can enter his/her session (this does not work with Catalyst Application - it is handled by Plugin::Session) SCENARIO 2: 1) the hacker goes to WebApp and gets a real sessionid (just by browsing anonymous part of WebApp) 2) hacker inserts (somehow) this values into a cookie in victim's browser 3) after the victim logs into WebApp the hacker can enter his/her session (this DOES WORK with Catalyst Application using pure "authenticate()") As a minimum I would recommend to add a note into a doc (probably to Plugin::Authetication) saying that preventing session fixation (scenarion 2) can be achieved by using login action like this (I have not found out anything better): sub login { my ( $self, $c ) = @_; ... if ($c->authenticate( { username => $user, password => $pass } )) { # login OK $c->create_session_id(); ... } else { # login FAILED ... } } It seems to be approximately what we needed. It creates a new session with a copy of data from old session (I have tested just with State::Cookie); however the function create_session_id(...) is declared as internal (probably not intended to be used from outside Plugin::Session) and I am not sure if the behaviour in this case is not more side effect than a feature. Apart from that there is a remaining issue that after calling create_session_id(...) the old session is not invalidated (if I switch cookie value back the old session still works but just with old [=pre-authenticate] session data - that is basically no threat). Has anybody more familiar with Plugin::Session a better idea how to "change session id and keep session data" during authentication? Thanks. -- kmx
Subject: Re: [rt.cpan.org #46318] Session fixation vulnerability
Date: Wed, 08 Jul 2009 00:08:31 +0200
To: bug-Catalyst-Plugin-Session [...] rt.cpan.org
From: kmx <kmx [...] volny.cz>
Hi, would you at least agree with adding a new method into Catalyst-Plugin-Session that can be called in order to force the sessionid change while keeping all session data? I have prepared my proposal as a SVN branche (incl. doc + test) here: http://dev.catalystframework.org/svnweb/Catalyst/log/Catalyst-Plugin-Session/0.00/branches/paranoid_session_fixation_protection/ -- kmx
Branch merged. Released to CPAN as 0.25. Thanks as always for the patches :)