I've got a python/WSGI app which needs to check to see if a user has logged on to a PHP web app. The problem is that the PHP app checks if a user has logged on by comparing a value in the $_SESSION variable to a value in the cookie from the user's browser. I would prefer to avoid changing the behavior of the php app if at all possible.
My questions:
Is there anyway I can access the session variables from within python? Where should I start to look?
Are there any obvious security/performance issues I should be aware of when taking this approach?
Depends on the PHP app, if it's keeping session data in a database (MySQL maybe) you can just connect to the database and get the data, if it's using native PHP sessions you should look to the session.save_path
config setting in php.ini, that's the place where the runtime saves files with the session data.
Once you have the data you can parse it to get it unserialized, take a look at how serialize()
and unserialize()
work in PHP.
I'm currently in the process of trying to run a python server side by side with an existing Apache/php one. A custom solution I arrived at was to save the $_SESSION as an encrypted cookie, letting the php authentication operate as before, then share a private key between the two servers.
Two issues:
- Up to you how to handle session expiry stuff.
- I haven't bothered with an Initialization Vector, assuming the time stamp from my expiry stuff is enough. See https://stackoverflow.com/a/12486940/4495503 for why I might be being too security lax...
Anyway, my php encrypted cookie function:
session_start();
$encryptToCookie = function($varToEncode,$cookieName,$privateKey){
$iv = $privateKey;
$pass = $privateKey;
$method = 'aes-128-cbc';
$encryptedString = openssl_encrypt(json_encode($varToEncode), $method, $pass, true, $iv);
setcookie($cookieName,bin2hex($encryptedString));
};
$encryptToCookie($_SESSION,"sessionEncrypted","yohoyohoyohoyoho"); // private key must be 16bit
And my python side decryption:
from subprocess import Popen, PIPE
import binascii
def decrypt(encryptedString,privateKey):
encryptedString = binascii.unhexlify(encryptedString)
pathToOpenSSL = 'C:\pysrc\openssl\openssl.exe' # MODIFY THIS!!
openssl = Popen([pathToOpenSSL,
'enc','-aes-128-cbc','-d',
'-nosalt','-nopad','-K',
privateKey.encode('hex'),
'-iv',
privateKey.encode('hex')],
stdin=PIPE,stdout=PIPE)
decryptedString = openssl.communicate(encryptedString)[0].replace('\x04','')
return decryptedString
decrypt(encryptedString,'yohoyohoyohoyoho')
Hope this is of help to someone, remember all the usual stuff about generating private keys and then being careful with them!