Nandini Bhaduri
Nandini Bhaduri

Reputation: 1855

The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'

How to solve :

Warning: session_start() [function.session-start]: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in ..... on line 3

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at ......:3) in ..... on line 3

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at .....:3) in ..... on line 3

Upvotes: 30

Views: 57362

Answers (10)

Jabavizhi
Jabavizhi

Reputation: 1

session_id() itself will happily accept invalid session ids, but if you try to start a session using an invalid id, you will get the following error:

Warning: session_start(): The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'

Upvotes: 0

Ensai Tankado
Ensai Tankado

Reputation: 343

You should check the sessionid for not allowed characters because the session_start() function in php is vulnerable for information disclosure.

So if you change the phpsessid cookie with a not allowed character, then you will get an error message if not surpressed by error_reporting or an "@" character in the front of session_start function.

Upvotes: 0

PiTheNumber
PiTheNumber

Reputation: 23542

I had the same problem and wrote a new version with PHP 8 syntax for my middleware class:

public function handle(Request $request, Closure $next)
{
    if (!headers_sent())
    {
        if(!$this->session_validate_and_start())
        {
            session_id( uniqid() );
            session_start();
            session_regenerate_id();
        }
    }

    return $next($request);
}

protected function session_validate_and_start()
{
    $sessid = $this->getSessionIdFromInput();

    if (!empty($sessid) && !$this->isSessionIdValid($sessid))
    {
        return false;
    }

    return session_start();
}

protected function getSessionIdFromInput(): string
{
    $sn = session_name();

    return $_COOKIE[$sn] ?? $_GET[$sn] ?? '';
}

protected function isSessionIdValid(mixed $sessid): bool
{
    return preg_match('/^[a-zA-Z0-9,\-]{22,40}$/', $sessid);
}

Upvotes: 0

EvilThinker
EvilThinker

Reputation: 750

It is an information vulnerability: a malicious attacker may alter the cookies and assign illegal characters to PHPSESSID to expose this PHP warning, which in fact contains juicy information like the file path and the username!

Upvotes: 47

danjfoley
danjfoley

Reputation: 808

I came with up this simple method, just try and catch the session start, and if there is a problem regenerate the session.

try {
   session_start();
} catch(ErrorExpression $e) {
   session_regenerate_id();
   session_start();
} 

Upvotes: 0

StevenWang
StevenWang

Reputation: 3816

If you don't care about other users (for example: if it's a private interface), just check you browser, find the cookie PHPSESSID (or the name you gave it), delete it, and refresh.

Upvotes: 2

alpere
alpere

Reputation: 1119

There is a bug report for this problem (https://bugs.php.net/bug.php?id=68063)

You can check the success of your session_start and generate the id if needed:

$ok = @session_start();
if(!$ok){
session_regenerate_id(true); // replace the Session ID
session_start(); 
}

Upvotes: 18

Sergey Eremin
Sergey Eremin

Reputation: 11080

have a look at this session_start() discussion for a work-around:

session_start() generate a warning if PHPSESSID contains illegal characters

Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /home/para/dev/mon_site/header.php on line 17

To avoid i wrote this :

   <?php
        function my_session_start()
        {
            if (ini_get('session.use_cookies') && isset($_COOKIE['PHPSESSID'])) {
                $sessid = $_COOKIE['PHPSESSID'];
            } elseif (!ini_get('session.use_only_cookies') && isset($_GET['PHPSESSID'])) {
                $sessid = $_GET['PHPSESSID'];
            } else {
                session_start();
                return false;
            }

           if (!preg_match('/^[a-z0-9]{32}$/', $sessid)) {
                return false;
            }
            session_start();

           return true;
        }
    ?>

Upvotes: 16

Cendak
Cendak

Reputation: 1040

I edited Andron's previous solution! (fix returned value) and added the evaluation output of my_session_start(). Previous solution solve problem with error message, but I need have to session started.

/**
 * @return boolean return TRUE if a session was successfully started
 */        
function my_session_start()
{
      $sn = session_name();
      if (isset($_COOKIE[$sn])) {
          $sessid = $_COOKIE[$sn];
      } else if (isset($_GET[$sn])) {
          $sessid = $_GET[$sn];
      } else {
          return session_start();
      }

     if (!preg_match('/^[a-zA-Z0-9,\-]{22,40}$/', $sessid)) {
          return false;
      }
      return session_start();
}

if ( !my_session_start() ) {
    session_id( uniqid() );
    session_start();
    session_regenerate_id();
}

Upvotes: 13

Andron
Andron

Reputation: 6631

I suggest to use "more correct" version of the function.

Several notes:

  1. More correct regular expression (allows characters in the range a-z A-Z 0-9 , (comma) and - (minus)) as described here.
    Regular expression depends on the php ini settings, like described here and here.
  2. Use session name method

So updated version looks like this:

<?php
    function my_session_start()
    {
        $sn = session_name();
        if (isset($_COOKIE[$sn])) {
            $sessid = $_COOKIE[$sn];
        } else if (isset($_GET[$sn])) {
            $sessid = $_GET[$sn];
        } else {
            session_start();
            return false;
        }

       if (!preg_match('/^[a-zA-Z0-9,\-]{22,40}$/', $sessid)) {
            return false;
        }
        session_start();

       return true;
    }
?>

Upvotes: 6

Related Questions