Forum Moderators: coopster
The PHP sessions I want to secure will be over an SSL link, so there is a degree more security, but that still doesn't prevent session id snatching.
Next I thought about encrypting the session in the server side RAM, which would certainly stop any casual snoopers, but still doesn't prevent either session snatching nor decrypting session data by accessing the server RAM holding the key.
So here is my ideal thought... encrypt the session information in server RAM, but don't provide the server any ability to unencrypt it. Not as mad as it sounds..... we now have completely secure unobtainable session data.
So how do we access it? Well each SSL session handshake is based on the exchange of public keys, the data is encrypted with the private key, and decrypted with the public one. There is also an exchange of some kind of message digest hashing.
So why not use this message digest encrypted inside an SSL tunnel to encrypt the server side session in RAM? That way the "decryption key" is stored on the client side, and presented on each request to decrypt the session in RAM. If you provide the wrong key, the server is unable to decrypt the session, if you request an arbitrary session, the server is again unable to decrypt it.
The only time session data is in an unencrypted state is after the client has provided the key, and for the duration of the PHP function.
The problem is I have no idea how to gain access to an SSL stream via PHP or indeed what hashes to use ;)
anyone got any thoughts?
asp
just before saving the session PHP generates a hash based on the $_SESSION variable, and then promptly encrypts that variable using that hash value. The hash value is then past to the client in the http stream (in the url maybe).
The server now has no knowledge nor ability to decrypt the session data, unless the client returns the hash value in the next request. Interestingly, this hash value will only decrypt the data in RAM if the $_SESSION data is unchanged, otherwise you just get back garbage. So now we not only have guarenteed session security but session integrity as well.
asp
I don't know if going to the full extent of encrypting the session data on the server side is that important. Your idea of having a key in the url has a flaw in it. That url will be requested and theirfore the url (and key) will be in the logs. If the server is comprimised then they can also see the logs and the key.
The idea of using the keys generated by apache/mod_ssl is a good one. Like you I have no idea how to do it. I also don't know how often they rotate.
Rather than just the IP address idea why not just use a random string as a "key". The session id and "key" combination will give access to the session.
Still though the IP address idea is one of the best ones. A remote user will need to break into the session from the same computer/proxy that the first user used. That gives you a fairly good measure of security.
Remember if you don't trust your server then you've already lost since the server has the private key for SSL transactions. Also remember that at some point all of the data will need to be in RAM cleartext before encryption. Since this is the case if the server is comprimised there will always be a point when it can be viewed.
daisho.
It seems that you really don't trust your server.Nah we use NetWare ;)
Firstly, the concept was to be overly secure rather than 'just good enough', I was also really trying to secure against buffer overflow attacks where PHP RAM will likely be more accessable than server side kernal RAM where (one would hope) there is some decent secure memory management.
Your point about the logs is certainly valid, though bearing in mind the $_SESSION hash value changes on each request, so they would be of limited value, though a valid point.
Your key suggestion is effectively what I am suggesting though the client not the server maintains it.
I was thinking something along the lines of:
function SecureStuff(){
$session = unserialize( mdecrypt_generic( $resource, $_SESSION ) );
//do stuff on unencrypted data
$_SESSION = mcrypt_generic( $resource, serialize( $session ) );
$session = 'Write some completely useless block of data the same size as $_session';
} Now the $_SESSION data is never decrypted as a global and only available as a local variable.
asp