December 24th, 2004, 04:22 AM
PHP Sessions and Security
First, thanks to the people who responded to my other thread here:
And I'd like to continue that discussion if possible with a focus on sessions. Heres the deal:
We have an administrator section of a website written in PHP. I'd like to hear suggestions securing this section as much as possible, riddance to functionality! The reason why I say this, is because I am writing an admin section for a CMS (very slowly unfortunately) that I will use myself and I am going to release for others to use as well. I hope to make it highly configurable, allowing simple or very specific policies.
I am paying special attention to this paper:
I'd also like it to be designed to prevent the effects of a session hijack. Something I realized was that I couldn't force a user to have a certain IP to access the admin section, because not everyone maintains an IP while they surf. I then looked at using browser agents, but those are kind of predictable and I'm trying to figure out another solution. I will still implement those policies, but I will allow it to be configured not to, for AOL users or whoever uses the CMS.
Those are the specifics.
Any suggestions regarding my comments, and also wild ideas are encouraged.
(Happy|Merry) .* everybody.
And anyone who criticizes my attempt at regex will be negged severely...
December 26th, 2004, 09:10 AM
I've read most of the document, and I'm pretty sure I understand what they are saying the threat is.
(I also feel bad that I seem to answer most of these kinds of questions )
Perhaps you could have the server randomly generate a (new) secret for each page, and require that secret to be submitted before processing the next page?
This would work by having all of the admin functions be carried out via POST Requests. When you enter the Admin Panel, the server makes a secret of some sort, and puts it on the page in the form of a variable. Like <INPUT TYPE="HIDDEN" NAME="secret" VALUE="452SVAEFASDetc.etc."> When the person click son something like "Delete User" the secret would automatically be passed to the server along with the other variables that are needed by "Delete User". The new page generates a new secret, and the old one is invalid. The secret is supposed to be random and not guessable.
Theoretically, this would make it impossible to ride the session, because if the person opens a link from their e-mail client, everything except the secret could be known. An invalid secret prevents the action from taking place. The person can't hit the back button after making a POST request because they would resubmit the old secret, invalidating their session.
It would appear to solve all problems, but I came up with some issues. What if they go to a page on their website, so their secret is valid, and click on a malicious link from there (or even load a malicious image tag URL)? If they are in the same FORM tag, or perhaps even in a DOCUMENT.secret thing, it could be a problem. You'd have to figure out how to keep the malicious link from riding the secret, by somehow seperating them or filtering the link(s)/image(s). Maybe you could have the secrets issued from the main admin page only (main admin page must be visited and secret issues before other pages work), where no malicious links could exist. This way bad image URL's would not work because they can't get the secret, although they can try/be invalidated?
Hopefully something made sense. The secrets requirement for the admin pages. Anyone see anything I missed with it? Or other ideas for Soda?
December 27th, 2004, 10:09 PM
I had that in mind to defeat session riding (it's also in the doc), but it still doesn't address a session hijack. If the session were to be sniffed, then an attacker could impersonate the victim. This attack could be made tougher by requiring a certain IP and user agent during a session, however IP's are not always static during a session, and user agents can be impersonated as well.
I'm having trouble being creative to address that issue. All I have to work with are IP's and browser headers it seems, none of which are reliable.
December 28th, 2004, 07:38 AM
You could invalidate the session as soon as a request with a bad "nonce"/token (tim_axe's secret), thus preventing further exploitation as soon as the legit user sends his next request with the now expired nonce.
(BTW, using such a nonce/token is a known practice which also help in preventing accidnetal resubmits of forms (like unknownigly buying a second computer because you hit the back button )
But really, if the attacker is able to sniff the session, it's pretty much already too late. Even if binding the session with the IP, if the attacker is in the path of the traffic, he could also spoof the IP... The only thing that can save you at that point is SSL and a vigilient user (who will notice if the ssl cert is invalid)
Credit travels up, blame travels down -- The Boss