evolution-cms / evolution

Welcome to the new evolution of MODX Evolution!
GNU General Public License v3.0
260 stars 96 forks source link

Error: The session id is too long or contains illegal characters in core/functions/preload.php:70 #2104

Closed q2apro closed 1 year ago

q2apro commented 2 years ago

I have got visits from a Russian hack bot who tried 1000s of requests.

Cannot modify header information - headers already sent by (output started at /core/functions/preload.php:70) « Evolution CMS Parse Error » Error : Cannot modify header information - headers already sent by (output started at /core/functions/preload.php:70)

I checked the error logs and found:

PHP Warning: session_start(): The session id is too long or contains illegal characters, valid haracters are a-z, A-Z 0-9 and '-, ' in /core/functions/preload.php on line 70

On Stackoverflow there are some solutions to prevent this problem: https://stackoverflow.com/questions/3185779/the-session-id-is-too-long-or-contains-illegal-characters-valid-characters-are

I think EVOCMS should implement one of those solutions so the error cannot be caused.

Dmi3yy commented 2 years ago

You can implement this and send PR :)

q2apro commented 2 years ago

This should fix the problem: https://github.com/modxcms/evolution/compare/master...q2apro:evolution:patch-1

But I could not test it.

q2apro commented 2 years ago

The bot was there again. The error appeared again.

PHP Warning: session_regenerate_id(): Cannot regenerate session id - session is not active in /core/functions/preload.php on line 76

New code to avoid the problem:

        $session_ok = @session_start();
        if (!$session_ok)
        {
            ob_start();
            session_start();
            session_regenerate_id();
        }
q2apro commented 1 year ago

Better fix:

$sessionname = session_name();

// safe session - see https://stackoverflow.com/a/33024310/1066234
if (isset($_COOKIE[ $sessionname ]) && preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[ $sessionname ])) 
{
    session_start();
}
else if (isset($_COOKIE[ $sessionname ])) 
{
    unset($_COOKIE[ $sessionname ]);
    session_start();
}
else 
{
    session_start(); 
}

// no session started, exit
if (session_status() === PHP_SESSION_NONE) 
{
    exit();
}