Session security

php.internals

Stut

19 years ago
Hi all, Just wanted to get your opinion on a discussion currently going on on the general list. Why does the PHP session extension not use something like the user agent to validate that a session ID has not been hijacked? Or is this something that just hasn't been implemented yet? -Stut

Antony Dovgal

19 years ago
On 29.05.2007 21:04, Stut wrote:
> Hi all, > > Just wanted to get your opinion on a discussion currently going on on > the general list. > > Why does the PHP session extension not use something like the user agent > to validate that a session ID has not been hijacked? Or is this > something that just hasn't been implemented yet?
Please elaborate.
-- Wbr, Antony Dovgal

Rasmus Lerdorf

19 years ago
Stut wrote:
> Hi all, > > Just wanted to get your opinion on a discussion currently going on on > the general list. > > Why does the PHP session extension not use something like the user agent > to validate that a session ID has not been hijacked? Or is this > something that just hasn't been implemented yet?
The user agent is trivial to spoof. If you are going to hijack someone's session, it is very easy to also hijack their user agent string, so I don't see how that solves anything. -Rasmus

Robert Cummings

19 years ago
On Tue, 2007-05-29 at 10:16 -0700, Rasmus Lerdorf wrote:
> Stut wrote: > > Hi all, > > > > Just wanted to get your opinion on a discussion currently going on on > > the general list. > > > > Why does the PHP session extension not use something like the user agent > > to validate that a session ID has not been hijacked? Or is this > > something that just hasn't been implemented yet? > > The user agent is trivial to spoof. If you are going to hijack > someone's session, it is very easy to also hijack their user agent > string, so I don't see how that solves anything.
I agree mostly, but in the case of idiots that post a URL to a site that includes a PHPSESSID in the URL it would provide a teency bit more protection from casual hijacking :) I agree more with Xing Xing's responde though, in that it belongs in the script layer. Cheers, Rob.
-- .------------------------------------------------------------. | InterJinn Application Framework - http://www.interjinn.com | :------------------------------------------------------------: | An application and templating framework for PHP. Boasting | | a powerful, scalable system for accessing system services | | such as forms, properties, sessions, and caches. InterJinn | | also provides an extremely flexible architecture for | | creating re-usable components quickly and easily. | `------------------------------------------------------------'

Rasmus Lerdorf

19 years ago
Robert Cummings wrote:
> On Tue, 2007-05-29 at 10:16 -0700, Rasmus Lerdorf wrote: >> Stut wrote: >>> Hi all, >>> >>> Just wanted to get your opinion on a discussion currently going on on >>> the general list. >>> >>> Why does the PHP session extension not use something like the user agent >>> to validate that a session ID has not been hijacked? Or is this >>> something that just hasn't been implemented yet? >> The user agent is trivial to spoof. If you are going to hijack >> someone's session, it is very easy to also hijack their user agent >> string, so I don't see how that solves anything. > > I agree mostly, but in the case of idiots that post a URL to a site that > includes a PHPSESSID in the URL it would provide a teency bit more > protection from casual hijacking :) > > I agree more with Xing Xing's responde though, in that it belongs in the > script layer.
Well, obviously you need an authentication layer separate from the session layer. If people are using the session extension as if it was an authentication layer, then they are amazingly misguided. The solution to that is not the session code, but better documentation. -Rasmus

Robert Cummings

19 years ago
On Tue, 2007-05-29 at 11:14 -0700, Rasmus Lerdorf wrote:
> Robert Cummings wrote: > > On Tue, 2007-05-29 at 10:16 -0700, Rasmus Lerdorf wrote: > >> Stut wrote: > >>> Hi all, > >>> > >>> Just wanted to get your opinion on a discussion currently going on on > >>> the general list. > >>> > >>> Why does the PHP session extension not use something like the user agent > >>> to validate that a session ID has not been hijacked? Or is this > >>> something that just hasn't been implemented yet? > >> The user agent is trivial to spoof. If you are going to hijack > >> someone's session, it is very easy to also hijack their user agent > >> string, so I don't see how that solves anything. > > > > I agree mostly, but in the case of idiots that post a URL to a site that > > includes a PHPSESSID in the URL it would provide a teency bit more > > protection from casual hijacking :) > > > > I agree more with Xing Xing's responde though, in that it belongs in the > > script layer. > > Well, obviously you need an authentication layer separate from the > session layer. If people are using the session extension as if it was > an authentication layer, then they are amazingly misguided. The > solution to that is not the session code, but better documentation.
Well the two are quite related. Not that the session is responsible for authentication, but once authenticated the session data (stored server side I hope) usually indicates whether a user has already performed authentication for the current temporary session -- otherwise you'd need to log back in on every request. As such, a URL posted in the wild containing a PHPSESSID is vulnerable to hijacking for the lifespan of the temporary session. Better documentation won't help the completely ignorant masses of end users :) Cheers, Rob.
-- .------------------------------------------------------------. | InterJinn Application Framework - http://www.interjinn.com | :------------------------------------------------------------: | An application and templating framework for PHP. Boasting | | a powerful, scalable system for accessing system services | | such as forms, properties, sessions, and caches. InterJinn | | also provides an extremely flexible architecture for | | creating re-usable components quickly and easily. | `------------------------------------------------------------'

Rasmus Lerdorf

19 years ago
Robert Cummings wrote:
> On Tue, 2007-05-29 at 11:14 -0700, Rasmus Lerdorf wrote: >> Robert Cummings wrote: >>> On Tue, 2007-05-29 at 10:16 -0700, Rasmus Lerdorf wrote: >>>> Stut wrote: >>>>> Hi all, >>>>> >>>>> Just wanted to get your opinion on a discussion currently going on on >>>>> the general list. >>>>> >>>>> Why does the PHP session extension not use something like the user agent >>>>> to validate that a session ID has not been hijacked? Or is this >>>>> something that just hasn't been implemented yet? >>>> The user agent is trivial to spoof. If you are going to hijack >>>> someone's session, it is very easy to also hijack their user agent >>>> string, so I don't see how that solves anything. >>> I agree mostly, but in the case of idiots that post a URL to a site that >>> includes a PHPSESSID in the URL it would provide a teency bit more >>> protection from casual hijacking :) >>> >>> I agree more with Xing Xing's responde though, in that it belongs in the >>> script layer. >> Well, obviously you need an authentication layer separate from the >> session layer. If people are using the session extension as if it was >> an authentication layer, then they are amazingly misguided. The >> solution to that is not the session code, but better documentation. > > Well the two are quite related. Not that the session is responsible for > authentication, but once authenticated the session data (stored server > side I hope) usually indicates whether a user has already performed > authentication for the current temporary session -- otherwise you'd need > to log back in on every request. As such, a URL posted in the wild > containing a PHPSESSID is vulnerable to hijacking for the lifespan of > the temporary session. Better documentation won't help the completely > ignorant masses of end users :)
You really want a separate and distinct signed authentication cookie that has nothing to do with the session. The stored session should indicate which logged in user the session belongs to, but it should never ever be used as the sole authentication cookie. That's what I meant by a separate authentication layer. -Rasmus

Stut

19 years ago
Rasmus Lerdorf wrote:
> You really want a separate and distinct signed authentication cookie > that has nothing to do with the session. The stored session should > indicate which logged in user the session belongs to, but it should > never ever be used as the sole authentication cookie. That's what I > meant by a separate authentication layer.
Thanks to everyone for their responses. The issue is not about how a user is initially validated, it's about how you prevent the session ID from being used on a different machine while it's still active on the server. AFAICT using a signed authentication cookie will not do this since it's still coming from the client and can therefore be copied. The basic question is... is there any way to validate that a session ID coming from the client is coming from the same client? I don't believe there is since, as Xing pointed out, anything that comes from the client can a) be faked, and b) may change from request to request. This includes the user agent and IP address. However, I'd like clarification on that just in case there's a reliable way to make sessions more secure. Oh, and also to validate the argument I'm making on PHP-General, but that's really a secondary goal ;) Cheers. -Stut

Stanislav Malyshev

19 years ago
>> You really want a separate and distinct signed authentication cookie >> that has nothing to do with the session. The stored session should >> indicate which logged in user the session belongs to, but it should >> never ever be used as the sole authentication cookie. That's what I >> meant by a separate authentication layer.
Could you explain why? If you can steal session cookie, you definitely could steal any other cookie too. So stealing-wise, nothing is gained by using separate cookie. Signing would help you to know the cookie is from you, but I don't see how it's going to help you to know the cookie belongs to whoever is attempting to use it. Could you elaborate?
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/

Rasmus Lerdorf

19 years ago
Stanislav Malyshev wrote:
>>> You really want a separate and distinct signed authentication cookie >>> that has nothing to do with the session. The stored session should >>> indicate which logged in user the session belongs to, but it should >>> never ever be used as the sole authentication cookie. That's what I >>> meant by a separate authentication layer. > > Could you explain why? If you can steal session cookie, you definitely > could steal any other cookie too. So stealing-wise, nothing is gained by > using separate cookie. Signing would help you to know the cookie is from > you, but I don't see how it's going to help you to know the cookie > belongs to whoever is attempting to use it. Could you elaborate?
The session store is just a session store. It is not a login/authentication mechanism and thus doesn't have any of the protections you might want to add to that. Therefore a separate authentication cookie is needed that can separate the two concepts completely. This also allows you to have different timeouts on the two. For example, many sites let you stay logged in for weeks, but for any critical operation they have a much shorter timeout so they ask you to re-enter your credentials in order to perform that critical action. Also, any pages that have some sort of user action, typically a form, will have a crumb in it which is a small signed bit of data which is usually in a hidden field. This helps prevent cross site request forgeries by making each form specific to the logged in user. But yes, there isn't any standard approach to prevent cookie theft. It is up to the application to come up with a set of checks and restrictions that best meet the specific needs of that app. -Rasmus

Stanislav Malyshev

19 years ago
> The session store is just a session store. It is not a > login/authentication mechanism and thus doesn't have any of the > protections you might want to add to that. Therefore a separate > authentication cookie is needed that can separate the two concepts
I don't see how it's "therefore". Yes, session is just a storage. But how you derive from it that authentication information can not be stored in this storage and how the separate cookie is helping you in any way make it more secure?
> completely. This also allows you to have different timeouts on the two.
That's a very specific case which doesn't really concern security but site policies. You could also expire values inside session, there are numerous wrappers doing it AFAIK, and even if you don't use such wrapper there's nothing hard in storing timestamp inside the session and expiring auth once the timestamp goes old.
> For example, many sites let you stay logged in for weeks, but for any > critical operation they have a much shorter timeout so they ask you to > re-enter your credentials in order to perform that critical action.
That doesn't mean it should be implemented using separate cookie.
> Also, any pages that have some sort of user action, typically a form, > will have a crumb in it which is a small signed bit of data which is > usually in a hidden field. This helps prevent cross site request > forgeries by making each form specific to the logged in user.
That's nice but again is not related to cookies or sessions. This can be done without having separate auth cookie.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/

Stanislav Malyshev

19 years ago
> The basic question is... is there any way to validate that a session ID > coming from the client is coming from the same client?
I'm afraid since there's no way (well, except for described below :) to uniquely and securely identify the clients I don't see how you could do that. You could use client certificates as a secure client identification, and then probably you could verify that current client presented the same valid certificate as before, but that doesn't really belong to sessions - it's external to sessions. Not sure how well PHP support for client certificates is, in any case unless you have a lot of control over your users they probably won't like to install any certificates. Also, if you use SSL (which you probably do if you care about security), as I see it most frequent way to steal the cookie is to control user's browser. If the hostile code gained control over the user's browser, it's essentially the same client, so you couldn't distinguish it from the legitimate code. You could of course tryng to counter replay attacks (which are only part of the possible attacks) by matching IPs and other auxiliary data but if you don't have secure ID for the client there would be cases when it could be still not enough.
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/

Jacques Marneweck

19 years ago
On 29 May 2007, at 7:16 PM, Rasmus Lerdorf wrote:
> Stut wrote: >> Hi all, >> >> Just wanted to get your opinion on a discussion currently going on on >> the general list. >> >> Why does the PHP session extension not use something like the user >> agent >> to validate that a session ID has not been hijacked? Or is this >> something that just hasn't been implemented yet? > > The user agent is trivial to spoof. If you are going to hijack > someone's session, it is very easy to also hijack their user agent > string, so I don't see how that solves anything. >
I think he's trying to figure out how to do something similar to using a 'browser fingerprint' as part of his session. One thing I noticed with doing creating and checking a 'browser fingerprint' a few years back was depending on what you were doing / using it would change things between requests. With web requests, a lot of things are easy to spoof from the client side. Locking a session to an IP address has it uses provided the user does not make their requests from various IP addresses like the AOL proxy farms used to do afaik. If you are really paranoid, use SSL and regenerate the session identifier on the first request from the user. That way it's not known. It's generally advised to regenerate the session identifier on privilege change. There is no real way of detecting if a session has been hijacked given for example for .za users we tend to be transparently proxied for requests to international sites, so forcing locking a session to a IP will lock that session to an ISP's netcache. Something along the lines of: if (!isset($_SESSION['initiated'])) { session_regenerate_id(); $_SESSION['initiated'] = true; } When you change privilege do something along the lines of session_regenerate_id(true); Which will delete the previous session and keep the current session information. YMMV. Regards --jm
> -Rasmus
-- Jacques Marneweck http://www.powertrip.co.za/ http://www.powertrip.co.za/blog/ http://www.ataris.co.za/ #include <std/disclaimer.h>

Xing Xing

19 years ago
Stut 写道:
> Hi all, > > Just wanted to get your opinion on a discussion currently going on on > the general list. > > Why does the PHP session extension not use something like the user > agent to validate that a session ID has not been hijacked? Or is this > something that just hasn't been implemented yet? > > -Stut >
Some http proxy may modify the user agent~ If there are some http proxy in a cluster, and one of them do some different on user agent, there must be a trouble. And, the other way, to aganst the attacker getting the real user agent, we could do something like: md5(user agent + secrete key) . then if the attacker get the string of md5, it is no use to forge the real user agent. Any way, this should be done in the script layer, not in the session mechanism. you need more security, do it in script, needn't, do nothing~~ Xing

Richard Lynch

19 years ago
On Tue, May 29, 2007 12:04 pm, Stut wrote:
> Hi all, > > Just wanted to get your opinion on a discussion currently going on on > the general list. > > Why does the PHP session extension not use something like the user > agent > to validate that a session ID has not been hijacked? Or is this > something that just hasn't been implemented yet?
Could be any of these reasons, I suppose: A) Anybody smart enough to hijack a session, is smart enough to send the same User Agent. B) Valid reasons exist for a user to switch User Agents mid-session, e.g., stupid broken browser bugs that can be worked around by "hijacking" one's own session. (I've done it, at least...) C) It's just too high a level to be done "right" in PHP core, imho. YMMV
-- Some people have a "gift" link here. Know what I want? I want you to buy a CD from some indie artist. http://cdbaby.com/browse/from/lynch Yeah, I get a buck. So?