Proper session hijacking prevention in PHP
php, security, session, session-hijacking, sessionid
Solution
Your configuration is awesome. You definitely read up on how to lock down php sessions. However this line of code negates a lot of the protection provided by your php configuration: `session_id(sha1(uniqid(microtime()));`
This is a particularly awful method of generating a session id. Based on your configurations you are generating the session id from `/dev/urandom` which is a awesome entropy pool. This is going to be a lot more random than uniqid() which is already mostly a timestamp, adding another timestamp to this mix doesn't help at all. Remove this line of code, asap.
Checking the IP address is problematic, ip addresses change for legitimate reasons, such as if the user is behind a load balancer or TOR. The user agent check is pointless, it is like having a GET variable like `?is_hacker=False`, if the attacker has the session id they probably have the user agent, and if they don't this value is really easy to brute force.
Problem
I know this topic has been discussed a lot, but I have a few specific questions still not answered. For example: ``` // **PREVENTING SESSION HIJACKING** // Prevents javascript XSS attacks aimed to steal the session ID ini_set('session.cookie_httponly', 1); // Adds entropy into the randomization of the session ID, as PHP's random number // generator has some known flaws ini_set('session.entropy_file', '/dev/urandom'); // Uses a strong hash ini_set('session.hash_function', 'whirlpool'); ``` ``` // **PREVENTING SESSION FIXATION** // Session ID cannot be passed through URLs ini_set('session.use_only_cookies', 1); // Uses a secure connection (HTTPS) if possible ini_set('session.cookie_secure', 1); ``` ``` session_start(); // If the user is already logged if (isset($_SESSION['uid'])) { // If the IP or the navigator doesn't match with the one stored in the session // there's probably a session hijacking going on if ($_SESSION['ip'] !== getIp() || $_SESSION['user_agent_id'] !== getUserAgentId()) { // Then it destroys the session session_unset(); session_destroy(); // Creates a new one session_regenerate_id(true); // Prevent's session fixation session_id(sha1(uniqid(microtime())); // Sets a random ID for the session } } else { session_regenerate_id(true); // Prevent's session fixation session_id(sha1(uniqid(microtime())); // Sets a random ID for the session // Set the default values for the session setSessionDefaults(); $_SESSION['ip'] = getIp(); // Saves the user's IP $_SESSION['user_agent_id'] = getUserAgentId(); // Saves the user's navigator } ``` So, my questions are - do the `ini_set`'s provide enough security? - is it okay to save the user's IP and navigator and then check it every time the page is loaded to detect a session hijack? Could this be problematic in any way? - is the use of `session_regenerate_id()` correct? - is the use of `session_id()` correct?