--- Hardik Doshi <[EMAIL PROTECTED]> wrote: > I read your article about session security on php magazine as well > as on php architect. Both are very nice articles.
Thank you. :-) > I would like to ask you what is the reason you are not suggesting > to use IP address as one of the parts in generating the fingerprint. My general approach to security is to make things are difficult as possible for the bad guys and as easy as possible for the good guys. This is a vague guideline, but it can help you to make good decisions, in my opinion. There are two situations which can be problematic when you depend on the IP address: 1. Multiple people can have the same IP address. 2. One person can have multiple IP addresses. Both of these situations are not only possible, but quite common in practice. As an example, all AOL users fall into the second category. So, it is my opinion that relying on the IP address does not offer much protection and can potentially cause your legitimate users a lot of problems. I think Web developers should focus on the information within HTTP and stay away from reliance on the TCP/IP stack. There are exceptions, of course, but only when you can be sure of the network topology of your users. This might be the case when you're developing an intranet application for a simple local network (users connect directly to your Web server and never go through an HTTP proxy). In this case, checking the IP should not adversely affect your users, and it requires one more hurdle for an attacker to overcome. > In php architect magazine (Feb) you have suggested to use > session_regenerate_id() on all the pages before i start session. That's not quite what I was suggesting. In order to prevent session fixation, I think you should regenerate the identifier anytime there is a change in privilege. Later in the article, I suggest regenerating the identifier anytime the user provides authentication credentials, but I also warn about passing along such a simplistic suggestion, because people can misinterpret this without a good understanding of the reasoning behind it. > In my application i am storing some variables temporarily into the > DB for the specific session ID. Now if session id changes from page > to page then how would i retrieve the information back from the DB? If you're doing something outside of PHP's session mechanism, you'll have to handle this yourself. If, however, you use PHP's mechanism, most everything will be transparent to you. PHP will set a new cookie, rewrite the URLs correctly, provide the correct information in SID, etc. Whatever your method of session identifier propagation, as long as you're using a standard PHP session feature, you should not have to change anything. > What is the reason you are suggesting to use that function? To prevent, or at least complicate, session fixation attacks. > Please let me know what should be the best combination of > fingerprint. Currently i am using SECRETWORD + user agent + accept > charset + session id and hashing it with md5(). Now if someone has > pointed that user agent changes for the same browser then i don't > think it's worth to add user agent. What do you think? I have always used User-Agent and have never encountered a problem. The only header I have seen to change from one request to the next on the same browser is the Accept header on certain versions of IE (I apologize for not having specific versions, but you can test this for yourself). When a user clicks Refresh, the Accept header was different than when the user clicked a link (or anything except Refresh, from my experience). You can probably work around this, but I decided it was best to not trust the consistency of the header. The reason that I always encourage User-Agent checking is that it is one of the most unique headers sent. I just checked the statistics of my Web site, and I have had more than 500 unique User-Agents access my site today. This makes prediction very unlikely, which is a nice characteristic. > I have one concern for securing the session variables. I may be wrong > here. If bad guy steals session id information then he can also > produce the same fingerprint too. If this is true, then you should change your approach. Above, you stated: Currently i am using SECRETWORD + user agent + accept charset + session id and hashing it with md5(). Assuming your secret padding isn't really SECRETWORD, or assuming that the attacker isn't subscribed to this list, this should be very difficult to predict. If an attacker has only been able to compromise a valid session identifier, he/she still has a few other things to obtain before a successful impersonation attack can be launched: 1. SECRETWORD 2. The User-Agent of the user's client (the user whose session identifier was stolen) 3. The Accept-Charset header sent by the user's client 4. The procedure you use to create the fingerprint I don't think this is very easy at all. Now, one very important thing to keep in mind is that because the user is passing this fingerprint to the server every time, there is a chance that it can also be compromised. A good approach is to propagate the session identifier and the fingerprint by using two different methods. This can mitigate the possibility that both are compromised at the same time. But, even if an attacker has obtained a valid session identifier and the associated fingerprint, because the fingerprint is an MD5, the attacker doesn't necessarily know the User-Agent and Accept-Charset headers that were used to create the fingerprint (unless the method used to obtain these provided this information as well, which is something that using SSL can help to prevent). Assuming you are checking these things each time, the attacker still can't impersonate the user. The valid headers must also be sent. Now, this is still possible, of course, but hopefully you can see that it is quite difficult. If you add in a small timeout, you can make the attacker's job even more difficult. If you add a bit of obscurity, you can help things even more (obscurity isn't as useless as people may lead you to believe). > Because right now i am storing the fingerprint into the session > variable and on everypage i am checking the expected fingerprint. You also want to be checking each thing that you used to create the fingerprint. As easy way to do this might be to simply regenerate the fingerprint each time and compare it to the one being presented. > Thanks for the nice articles. I am waiting for your future security > tips on php architect magazine. I am finishing up one on shared hosting right now. It should be in this month's issue of php|architect, although I am currently past my deadline. :-( Hope that helps. Chris ===== Chris Shiflett - http://shiflett.org/ PHP Security - O'Reilly Coming mid-2004 HTTP Developer's Handbook - Sams http://httphandbook.org/ PHP Community Site http://phpcommunity.org/ -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php