The PHP docs on session_name() say:
It should contain only alphanumeric characters; it should be short and descriptive (i.e. for users with enabled cookie warnings). ... The session name can't consist of digits only, at least one letter must be present. Otherwise a new session id is generated every time.
So it's clear you must have something non-numeric in there, but it's not quite clear what characters you can't have. The cookie spec itself denies ()<>@,;:\"/[]?={}, but that still leaves others that might be permitted but are not strictly alphanumeric. This is important because cookie security prefixes use - and _ in names like __Secure-PHPSESSID. So I had a rummage in the PHP source code at the session_name function – but I can't see that it does anything other than check it's a string. In practice, it works fine, but I'd be more comfortable knowing precisely why! For example, this works:
session_name('__Secure-PHPSESSID');
session_start();
$_SESSION['test'] = $_SESSION['test'] . "\n" . rand(0,100);
var_dump($_SESSION);
So what are the actual limits on PHP session names?
I got a bit further with this. The rules for a session name are defined in this validation function, which permits
[a-zA-Z0-9,-]{1,256}(but not numeric-only). You can have commas and dashes in session names in addition to alphanumerics, so the docs are wrong on that. This function is called from an internalsession_create_idfunction, which triggers a warning if the session name doesn't pass that validation.Despite this, no warning is triggered when passing in a session name containing
_. This is demonstrable:This works perfectly, triggering no errors or warnings, and shows a growing list of random numbers (showing that the session storage is working and therefore the cookies are too), and the second
session_namecall with no params shows the session name that we set:And the HTTP headers show that the script sets a cookie called
__Secure-MySession:I also tried naming the session
My_Session, just in case PHP looks for explicit__Session-prefix, but that works just fine too. Other characters like#or(do not trigger an error either; in those cases the session name is URL-encoded, which looks remarkably like this bug that was fixed quite a while ago. As expected,123,works, but also URL-encodes the comma.So while this demonstrates that having
_in session names works fine, I can't tell you why. I've asked elsewhere too, and if I find out, I will update this question!Coincidentally, draft 06 of RFC6265bis expires today.