Skip to content

Bug: get_cookie() cookie prefix behavior #6009

Closed
@colethorsen

Description

@colethorsen

PHP Version

7.3

CodeIgniter4 Version

4.1.9

CodeIgniter4 Installation Method

Composer (as dependency to an existing project)

Which operating systems have you tested for this bug?

macOS, Linux

Which server did you use?

apache

Database

MySQL 8

What happened?

The cookie prefixing to prevent collisions doesn't exactly work as expected. There is an issue with at least the get_cookie() helper function. The cookie prefix is specifically toted as a way to prevent collisions, however this function doesn't solve for collisions.

    function get_cookie($index, bool $xssClean = false)
    {
        $prefix  = isset($_COOKIE[$index]) ? '' : config(App::class)->cookiePrefix;
        $request = Services::request();
        $filter  = $xssClean ? FILTER_SANITIZE_FULL_SPECIAL_CHARS : FILTER_DEFAULT;

        return $request->getCookie($prefix . $index, $filter);
    }

This function looks to see if the base cookie without the prefix exists, and if it does not exist then it looks for the prefixed cookie. It should look for the prefixed cookie and reject the un-prefixed cookie entirely, otherwise it creates collisions.

Steps to Reproduce

If you take the following example:

Config/App.php
public $cookiePrefix = 'prefix_';

Theoretical array of cookies:

$_COOKIES = [
    'prefix_test' => 'Right Value',
    'text'        => 'Wrong Value',
];

get_cookie('test');

returns 'Wrong Value' by default, ideally it should return 'Right Value' and even if 'prefix_text' is not set, it should return null and never 'Wrong Value'

Expected Output

returns 'Wrong Value' by default, ideally it should return 'Right Value' and even if 'prefix_text' is not set, it should return null and never 'Wrong Value'

Anything else?

This could be fairly easily fixed by just enforcing the prefix:
$prefix = config(App::class)->cookiePrefix ?? '';

However, I'm not sure if this should be enforced at a deeper stage of getting the cookie, and/or the function should be extended to allow for a prefix to be set independently if desired like:

    function get_cookie($index, bool $xssClean = false, string $prefix = null)
    {
        $prefix  = $prefix !== null ? $prefix : config(App::class)->cookiePrefix;
        $request = Services::request();
        $filter  = $xssClean ? FILTER_SANITIZE_FULL_SPECIAL_CHARS : FILTER_DEFAULT;

        return $request->getCookie($prefix . $index, $filter);
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugVerified issues on the current code behavior or pull requests that will fix themdocumentationPull requests for documentation only

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions