session_start() issues regarding illegal characters, empty session ID and failed session

后端 未结 3 1668
Happy的楠姐
Happy的楠姐 2021-02-13 14:53

So, I realise this is a repeat question however, it is apprently a bug yet the original post for this is 5 years old but it\'s also said that it\'s a malicious

相关标签:
3条回答
  • 2021-02-13 15:32

    My bet would be, you were under attack at this time. This means someone manipulated your session cookie for example.

    Since session_start(); is a system function, I don't think it would generate invalid ids.

    In my opinion, option 2 is the best. But if I remember correct, you need to set a custom error handler for this.

    This answer seems better for me:

    $ok = @session_start();
    if(!$ok){
       //Hello Hacker ;)
       session_regenerate_id(true); // replace the Session ID
       session_start(); 
    }
    
    0 讨论(0)
  • 2021-02-13 15:33

    I like the explanation of Pedro Lobito but the algorithm can be improved:

    if (isset($_COOKIE[session_name()]) && 0 === preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[session_name()])) {
        unset($_COOKIE[session_name()]);
    }
    
    if ('' === session_id()) {
        session_start();
    }
    
    0 讨论(0)
  • 2021-02-13 15:48

    The problem:

    session_start() relies on $_COOKIE[session_name()], so, if you edit the cookie value to something like #$#$FDSFSR#"#"$"#$" or simply empty it (not delete the cookie) and refresh a page with your code:

    if (!session_id()) {
        session_start();
    }
    

    The following warning is generated:

    PHP Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /home/username/public_html/session_start.php on line 7

    This happens because php is checking if session_id() exists and, in fact, it exists, but contains illegal characters not allowed as session_id name.

    A valid session id may contain only digits, letters A to Z (both upper and lower case), comma and dash ([-,a-zA-Z0-9]) between 1 and 128 characters.


    My solution:

    Check if $_COOKIE[session_name()] is set and contains a valid session_id prior to session_start(), otherwise, delete the session cookie and only then session_start(), something like:

    function safeSession() {
        if (isset($_COOKIE[session_name()]) AND preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[session_name()])) {
            session_start();
        } elseif (isset($_COOKIE[session_name()])) {
            unset($_COOKIE[session_name()]);
            session_start(); 
        } else {
            session_start(); 
        }
    }
    

    start the session:

    safeSession();
    

    NOTES:

    1 - session_name is defined on your php.ini as session.name = SOMETHING (default is PHPSESSID), so, you may be looking for a cookie matching session.name. You can use the session_name() function to retrieve it.

    2 - Session cookie manipulation can be used by hackers to dump information from your server (username and path) if ini_set('display_errors', 1); is set.

    3 - session_regenerate_id(true) works but, because it checks the current session_id prior to assign a new one, generates warnings.

    4 - I've tested the code with several invalid session names and no errors or warnings were generated, everything worked and intended.


    References:

    session.c Source Code

    0 讨论(0)
提交回复
热议问题