Protect from people bruteforcing the PHPSESSID The PHPSESSID is stored in the clients cookie so I don't consider it as secure. Someone might bruteforce it and perform some action (like a Facebook status post) whenever a session was successfully hijacked.

I was wondering how I can protect against attacks like that. Maybe by locking out suspect users? My solution I came up with is a bit different:

&lt;?php

    $lifetime = 1 * 60 * 60; // seconds

    // Rename the PHPSESSID cookie for convenience and set the maximum lifetime
    ini_set('session.name', 'session_id');
    ini_set('session.gc_maxlifetime', $lifetime);
    session_set_cookie_params($lifetime);

    // Create a new session if necessary
    if ( ! isset($_COOKIE['session_id'])) {
        @session_start() or die(); // Don't output anything on invalid cookie forgery attempts

        // Generate a random lowercase alphanumeric string
        $sessionKey = substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyz', 5)), 0, 32);

        // Save it in the session and as a cookie
        setcookie('session_key', $sessionKey);
        $_SESSION['session_key'] = $sessionKey;

        $_SESSION['foo'] = 'bar'; // Just for testing – see the last echo statement in this script
    }
    else {
        @session_start() or die(); // Don't output anything on invalid cookie forgery attempts

        // Destroy the session completely (including client cookies) if the session keys don't match
        if ($_SESSION['session_key'] !== $_COOKIE['session_key']) {
            session_unset();
            session_destroy();
            setcookie('session_id', null, time() - 1);
            setcookie('session_key', null, time() - 1);
        }
    }

    echo isset($_SESSION['foo']) ? $_SESSION['foo'] : 'baz';

?&gt;


What do you think about it? Can I consider this as secure or are any other steps required? Will it protect me successfully from the described attacks?
Depending of the attack, your code might be either may be more secure than the traditional use of PHP sessions.



If the attacker gets the session_id cookie from an XSS attack, he also gets access to the session_key one, and your code won't protect sessions from being hijacked. You can avoid this by setting the HttpOnly flag on your cookies, making them not accessible by JavaScript through document.cookie :


Using ini_set('session.cookie_httponly', 1); will configure PHP to add the flag on the session_id cookie.
Setting the seventh parameter of the setcookie function to true will set the HttpOnly flag on the session_key cookie. More information about all the parameters can be found on the official documentation : http://php.net/manual/function.setcookie.php




Anyway, that won't protect from the man in the middle attacks.
PHP has a function named session_regenerate_id which changes the current session id by a new one, making the hijacked cookies obsolete.

All you need to do is calling this function once you've started the session : http://php.net/manual/en/function.session-regenerate-id.php



If the attacked gets the session_id cookie from bruteforce, then your solution is indeed more secure, but you should still have a look to the two settings mentioned above.

Note that substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyz', 5)), 0, 32); doesn't generate a true random lowercase alphanumeric string since each character won't appear more than 5 times. substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyz', 32)), 0, 32); will work.



There are also more php.ini settings to add more entropy to PHP sessions ids :


The session.hash_function setting changes the hash function used by PHP to generate the id.
The session.entropy_file and session.entropy_length settings will tell PHP to use an external file as a source of additional entropy when generating the id.