Page 1 of 1
Advanced PHP cookies
Posted: Mon Oct 17, 2005 9:30 am
by dandri
I have created a PHP class that uses MySQL database to store session information. As a security measure, everytime the client browser sees session pages, a new MD5 key is generated and sent to the client just like TCP sequence numbers. This MD5 key is sent to the client browser via a dedicated cookie. So, if the session ID has been compromised, the cracker should also find the MD5 key, otherwise the session is considered invalid and finally destroyed.
The session class works fine. However, when I hit the session pages more that 2-3 times per second, there some time when the client has not been informed with the latest MD5 cookie, though I saw from Ethereal that the server has actually sent it. This resulted in invalidating the session, of course.
Posted: Mon Oct 17, 2005 9:41 am
by Chris Corbyn
Hmmm... I'm not sure but maybe output buffering could be of use here.. not 100% quite how

Posted: Mon Oct 17, 2005 10:31 am
by dandri
I tried output buffering, but the result was the same.
Posted: Mon Oct 17, 2005 10:42 am
by pickle
The problem is likely that your client hasn't loaded the page (the cookie headers in particular) before the page is loaded again. Throw Ethereal onto the client computer and see what's being sent.
You could keep a history of the last X number of keys generated, but someone'll always want to load the page X+1 times. Not too sure what you can do to fix this unfortunately.
Re: Advanced PHP cookies
Posted: Mon Oct 17, 2005 10:45 am
by Roja
dandri wrote:...a new MD5 key is generated and sent to the client just like TCP sequence numbers. This MD5 key is sent to the client browser via a dedicated cookie.
Thats not quite how TCP sequence numbers work.
The important differences are that TCP sequence numbers can resync in case of a dropped sequence, and that it occurs multiple times in a single stream, while cookies are one-shot per transfer (which may be dozens of http requests).
In other words, your described solution is much more "brittle". Its not as flexible, and you've seen the result of that brittleness.
dandri wrote:So, if the session ID has been compromised, the cracker should also find the MD5 key, otherwise the session is considered invalid and finally destroyed.
Always ask what problem you are trying to solve. Here, if the session id has been compromised, it means the attacker either compromised the browser and got the cookie directly, or sniffed the traffic and grabbed it off the line.
In the first case, *nothing* you do will prevent the theft. The attacker has the same resources and responses as the real client, so there is no differentiating. You can try to reduce the level of loss, but even that might be a waste.
In the second case, the odds of the attacker sniffing the session id and NOT being able to also sniff the cookie with the sequence number is virtually zero. You gain very little additional security for that scenario.
So, I'm curious what problem you were looking to solve.
dandri wrote:The session class works fine. However, when I hit the session pages more that 2-3 times per second, there some time when the client has not been informed with the latest MD5 cookie, though I saw from Ethereal that the server has actually sent it. This resulted in invalidating the session, of course.
Exactly. Without knowing what problem you tried to solve, its hard to balance the cost with the benefit. Based on the above assumptions about what you were trying to accomplish, I think the result is clearly very little additional security, and tremendous loss in usability.
Of course, its a Monday, and I might be too asleep to notice something far more interesting and important. Feel free to correct me.

Posted: Tue Oct 18, 2005 4:05 am
by dandri
Thanks 'Roja' for your comments. Please note that the MD5 key, used as a security measure, has the following role: Assume that a hacker manages to get session ID and, of course, the MD5 key. While the legitimate user keeps clicking on the session pages, the session ID remains the same but the MD5 key does not. So, a hacker can only use a session ID and a MD5 key pair, only if the legitimate user stays inactive, soon after these two keys are compromised. However, I have developed other measures for this perpose, such as checking the user agent string and only the first two octets of the IP address (in case the user is behind a proxy-cluster). Please note that we don't talk about 100% of security.
As for the MD5 key, I'm sure that this is transmitted with the cookie, as the the 'setcookie()' returns true. After all, Ethereal can prove this. However, I cannot check if the client's browser receives it. I'm sure that if I Ethereal on client's machine I will see the packet, since this packet is sent by the HTTP server. However, I cannot be sure if the client's browser actually stores it in its filesystem.
Is there any way to verify that the client's browser has actually received a specific cookie, besides using the 'header()' and 'exit()' functions?
Posted: Tue Oct 18, 2005 5:19 am
by Roja
dandri wrote:Thanks 'Roja' for your comments. Please note that the MD5 key, used as a security measure, has the following role: Assume that a hacker manages to get session ID and, of course, the MD5 key. While the legitimate user keeps clicking on the session pages, the session ID remains the same but the MD5 key does not.
Okay, then all you have done is decreased the window for the attacker to work in. You can do the same thing in a less brittle fashion by simply using session_regenerate_id, as suggested in many best practices now. Granted, I wouldn't do it on every page (because soon it becomes similarly brittle), but at least you aren't using two different systems for the same effect.
dandri wrote:However, I have developed other measures for this perpose, such as checking the user agent string and only the first two octets of the IP address (in case the user is behind a proxy-cluster).
This has been covered dozens of times on these forums. The user agent string can and does change frequently on a number of systems. Behind a proxy, through AOL, through some gateways (users connecting from work), and more - all are automated situations where the user's agent string is replaced by the gateway/proxy/software, changing it without them doing a thing. That also ignores the fact that an attacker can trivially spoof it.
The IP address is
completely, totally, 100% useless, as every octet can and does change if you are on AOL. Their proxy concentrators will change from east coast to west coast in a single http session - again, without any effort on the part of the user (or notice).
dandri wrote:Please note that we don't talk about 100% of security.
Please note that you do talk about 0% of consistency.
dandri wrote:As for the MD5 key, I'm sure that this is transmitted with the cookie, as the the 'setcookie()' returns true. After all, Ethereal can prove this. However, I cannot check if the client's browser receives it. I'm sure that if I Ethereal on client's machine I will see the packet, since this packet is sent by the HTTP server. However, I cannot be sure if the client's browser actually stores it in its filesystem.
Correct. The client can refuse cookies. Some sites put the figure as high as 10% of users are now blocking *all* cookies. Which is why using session_id is more beneficial. PHP transparently handles the session id appending for you, and has built in functions (like session_regenerate_id) that can increase the security.
dandri wrote:Is there any way to verify that the client's browser has actually received a specific cookie, besides using the 'header()' and 'exit()' functions?
You could check the cookie *after* the next page load, but not in the same page, no.
Posted: Tue Oct 18, 2005 10:33 am
by dandri
I didn't know about session_regenerate_id() function. It actually covers what I want to do, and it fitted very well with the custom session handlers I have developed. However, I've got the same problem when I hit the session pages with a rate higher than 3-4 times/sec. Even when I regenerate the session ID every 15 hits, I noticed this problem, which occurs in a very random way; I mean that I may hit 20-30 times a session within 8 seconds, and everything goes fine.
Of course, I admit that in normal cases, I don't expect a user to hit session pages more than 1 time/sec. So I can afford the above disadvantage. Indeed, this might be a security measure against brute force attacks, as a session can be normally hited with a rate higher than 3-4hits/sec only by a program and not mouse-clicks.
However, I didn't figure out the reason of that problem. Does this have to do with PHP, the Web browsers, or the network? I can't blame PHP, as the HTTP server actually sends client the session cookie. I cannot blame the network, either, as the problem occurs even on the localhost.
I would like also to tell 'Roja' that the propagation of session ID via cookies is the safest mathed, as books say. Indeed, when high security is important, you'd better leave users unwilling to accept cookies outside your application. As for the IP address and user agent filtering, these may surely change from request to request. For this reason my PHP class can optionally do these checks. This is because there are cases when these entities do not change, for example when mobile phone subscribers of the an operator use a WAP service of this opeartor.
Posted: Tue Oct 18, 2005 2:53 pm
by Roja
dandri wrote:I didn't know about session_regenerate_id() function. It actually covers what I want to do, and it fitted very well with the custom session handlers I have developed. However, I've got the same problem when I hit the session pages with a rate higher than 3-4 times/sec. Even when I regenerate the session ID every 15 hits, I noticed this problem, which occurs in a very random way; I mean that I may hit 20-30 times a session within 8 seconds, and everything goes fine.
It could be a number of things.
First, the network may drop it. You mention monitoring it, and seeing it transmitted, but I wonder if you are checking at the webserver, or at the receiving client.
Second, the browser might not be keeping up. That can happen for any number of reasons. Although I am a huge Firefox fan and supporter, Opera handles the network stack *far* faster in my opinion, so I would test with Opera for that issue. If you continue to see it..
Third, the cookie might not be stored because the time between cookies was too short. The browser doesnt update cookies that havent changed, or that are less new than a certain amount of time. It may be that the time is too short, considering how fast you are talking about sending them.
You are giving a very unique, very special timing and testing situation, and pinpointing the cause would be challenging at best.
Glad you like the session_regen function. Its awesome.
dandri wrote:I would like also to tell 'Roja' that the propagation of session ID via cookies is the safest mathed, as books say.
I didn't disagree. I simply cited the fact that up to 10% of users can and do block cookies. For them, your "safest" method locks them out entirely. ie, 0% functionality. Whereas by using php's native session_id, it can (if the user blocks cookies, and if you dont disable it) transparently switch to post and get for passing the session id.
dandri wrote:Indeed, when high security is important, you'd better leave users unwilling to accept cookies outside your application.
I completely disagree. I'd be more willing to simply use SSL, and not care about session cookies. Then the attacker cannot sniff the line, the session id can be regenerated often, and the attacker's window is tiny - all without cookies.
dandri wrote:As for the IP address and user agent filtering, these may surely change from request to request. For this reason my PHP class can optionally do these checks. This is because there are cases when these entities do not change, for example when mobile phone subscribers of the an operator use a WAP service of this opeartor.
I can name two major carriers that do change those items during a session: Verizon Wireless and T-Mobile. I worked for VZW, and I was a customer on T-Mobile. Both can and often do change both the ip and the user agent for users during a single session. I tested on both.
As I said, IP address is 100% unreliable, as is user agents.