1

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?

8
  • 1
    It says it right there: "only alphanumeric characters". Just letters and numbers, and not all numbers.
    – Barmar
    Commented Oct 22, 2020 at 17:10
  • 1
    I know that, it's why I quoted the docs. Please read the question – it works fine with session names containing - and _, so I want to know exactly what the constraints are, not just what the docs say, as these are evidently not necessarily the same thing.
    – Synchro
    Commented Oct 22, 2020 at 17:11
  • 2
    It doesn't enforce the requirement, I think it's just anticipating possible problems that could occur, so it's specifying a conservative requirement.
    – Barmar
    Commented Oct 22, 2020 at 17:13
  • 2
    It's possible that there used to be actual restriction in the code and they never updated the docs. OTOH, they also could be allowing for adding restriction in the code later, and you shouldn't depend on the current implementation.
    – Barmar
    Commented Oct 22, 2020 at 17:15
  • 1
    See this comment in the documentation, but it's 15 years old and may be obsolete.
    – Barmar
    Commented Oct 22, 2020 at 18:38

1 Answer 1

0

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 internal session_create_id function, 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:

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
session_name('__Secure-MySession');
session_start();
if (!array_key_exists('test', $_SESSION)) {
    $_SESSION['test'] = '';
}
$_SESSION['test'] .= "\n" . rand(0,100);

var_dump($_SESSION);
echo session_name();

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_name call with no params shows the session name that we set:

__Secure-MySession

And the HTTP headers show that the script sets a cookie called __Secure-MySession:

Headers showing correct session name in cookie

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.