Search code examples
phpsessionspecial-charactersfile-format

Reserved characters in PHP $_SESSION variable keys


I was looking at the internal representation of PHP session file and I noticed that the session keys are separated by the pipe character |.

Before getting into the problem I encountered, let me give a quick tutorial on how the session file is formatted. At least, this is how it was formatted on my Mac (10.9.4, PHP 5.4.24).

Session File Format

Say I have the following code:

$_SESSION["age"] = 26;
$_SESSION["car"] = "Mazda";
$_SESSION["nerdy"] = true;
$_SESSION["likes"] = array(42, "being meta");
$_SESSION["stats"] = array("bmi" => 1000);

Then it gets stored in the session variable like this:

age|i:26;car|s:5:"Mazda";nerdy|b:1;
likes|a:2:{i:1;i:42;i:2;s:10:"being meta"}
stats|a:1:{s:3:"bmi";i:1000}

The general format is

session_key|session_value[;session_key|value] etc.

where session_value is of the general form

type[:size]:value

More specifically (if anyone's interested),

  • strings: s:3:"some text"
  • integers: i:4
  • booleans: b:1 (true) or b:0 (false)
  • arrays: a:2:{session_value;session_value;session_value;session_value}

where the four session_values in the array of size 2 are the key;value key;value pairs.

The Problem

You can see that in the above, the top-level session keys are separated by the | character. But what if one of our session key names includes the | character?

Well, I tried it. And when I did, the entire session file (in /tmp) was blank (and the variables were definitely not set). Is this an oversight by the PHP devs or an undocumented limitation (or is it documented somewhere)?

This could be easily solved by putting the $_SESSION keys themselves in quotes or backslashing any pipe in a $_SESSION key string. This isn't a big problem for me personally, since I can't fathom why I would need to put a | in a $_SESSION variable key - just curious about it.


Solution

  • Its a known bug

    https://bugs.php.net/bug.php?id=33786

    The work around is update to 5.5.4 and use the php_serialize session serializer