Description
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);
}