Reputation: 1855
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
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
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
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
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
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
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
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
Reputation: 11080
have a look at this session_start()
discussion for a work-around:
session_start()
generate a warning if PHPSESSID contains illegal charactersWarning: 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
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
Reputation: 6631
I suggest to use "more correct" version of the function.
Several notes:
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