Skip to content

Session name with . or [ silently fails instead of giving warning/error #9932

Closed

Description

@Sjord

Description

The following code:

<?php
session_start(['name' => 'a.b']);

Resulted in no output, and $_SESSION variables are not stored.

But I expected this output instead:

Warning: session_start(): session.name cannot contain any of the following '.[=,; \t\r\n\013\014' in /var/www/html/test.php on line 2

Session simply reads $_COOKIE, and space , period . and opening square bracket [ are replaced by underscores. So setting a session name of a.b writes and reads a cookie called a.b, but $_COOKIE actually contains a_b. This makes session storage silently fail.

In a perfect world, session names could contain these characters, but I think a quick and easy fix is to add . and [ to the list of disallowed characters in session names, here:

/* Prevent broken Set-Cookie header, because the session_name might be user supplied */
if (strpbrk(PS(session_name), "=,; \t\r\n\013\014") != NULL) {   /* man isspace for \013 and \014 */
	php_error_docref(NULL, E_WARNING, "session.name cannot contain any of the following '=,; \\t\\r\\n\\013\\014'");
	return FAILURE;
}

The documentation already says it should contain only alphanumeric characters.

PHP Version

PHP 8.2 RC 6

Operating System

Debian 11.5

Activity

  1. hormus commented on Nov 12, 2022

    @hormus

    https://www.php.net/manual/en/language.variables.external.php

    For compatibility you must use characters allowed when creating a variable, although using the cookie you must be compatible with the url cookie_name=id_value as well as the valid syntax to create $cookie_name variables

    https://www.php.net/manual/en/function.setcookie.php
    Note: Using separator characters such as [ and ] as part of the cookie name is not compliant to RFC 6265, section 4, but supposed to be supported by user agents according to RFC 6265, section 5.

    the historical reason is register_globals automatically created the variables as not all characters are valid for the variable name we have decided to use
    https://www.php.net/manual/en/language.variables.basics.php As a regular expression, it would be expressed thus: ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

    <?php
    
    // $var[ = 'Hello'; //invalid
    // $var. = 'Hello'; //Invalid
    // $var+ = 'Hello' //invalid
    // $var= = 'Hello' //invalid
    // $var& = 'Hello' //invalid
    //$var['b'] = 'Hello' // Valid array $var and first creation of $var
    
    //Variables variable syntax
    ${'var2['} = 'Hello word';
    var_dump(${'var2['}); // Output Hello word and first creation of $var2[ variable
    
    
    // array
    // [ is %5B
    $var['+%5B'] = '/some_path/index.php?a=hello word';
    echo 'https://www.domain.tld' . str_replace(array('%2F', '%2f', '%3F', '%3f', '%3D', '%3d'), array('/', '/', '?', '?', '=', '='), urlencode($var['+%5B']));
    echo "\r\n";
    
    ?>

    previously the first page use $_SESSION['hi'] = 'user'; and this explains the creation of my $t variable

    <?php
    
    ob_end_clean();
    
    $i256 = str_replace(',', '', '115,​792,​089,​237,​316,​195,​423,​570,​985,​008,​687,​907,​853,​269,​984,​665,​640,​564,​039,​457,​584,​007,​913,​129,​639,​936');
    error_reporting((int) $i256);
    $t = true;
    ob_start();
    session_name('a[b]');
    session_start();
    ob_end_clean();
    if(isset($_SESSION['hi'])) {
    $t = false;
    }
    $text = ini_get('session.save_path') . '/sess_' . $_COOKIE['a']['b'];
    
    function get_include_contents($filename) {
        //if (is_file($filename)) {
            ob_start();
            include $filename;
            $var = ob_get_contents();
            ob_end_clean();
            return $var;
        //}
        return false;
    }
    $string = get_include_contents($text);
    $_SESSION['hi'] = 'user2';
    var_dump($string);
    
    ?>

    Expected and actual result:

    string(14) "hi|s:4:"user";"
    

    in this example $t is true means $_SESSION not retrieved but written to the file

    @Sjord although php automatically creates the array of $_COOKIE['a'] (eg $_COOKIE['a']['b']) my example adapted to the code proposed above session_start(['name' => 'a[b']) and $_COOKIE['a_b'] retrieves the value directly from the file

  2. added a commit that references this issue on Nov 15, 2022
    6fa26b1
  3. added a commit that references this issue on Mar 29, 2024
    a4298c1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions