====== PHP RFC: Cookies Having Independent Partitioned State (CHIPS) ====== * Version: 0.9.1 * Date: 2025-07-12 * Author: Dmitrii Derepko, xepozzd@gmail.com; Niels Dossche, dossche.niels@gmail.com * Status: Voting * Implementation: https://github.com/php/php-src/pull/12652 ===== Introduction ===== Modern browsers have several security levels to separate cross-site communications, including various settings to how cookies should behave across the sites. CHIPS is best explained by the description on [[https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies|MDN]]:
Cookies Having Independent Partitioned State (CHIPS, also known as Partitioned cookies) allows developers to opt a cookie into partitioned storage, with a separate cookie jar per top-level site. Without cookie partitioning, third-party cookies can enable services to track users and associate their information across unrelated top-level sites. Cookies marked Partitioned are double-keyed: by the origin that sets them and the origin of the top-level page.
CHIPS is necessary to keep cross-site cookies working properly, as Google Chrome has been phasing third-party cookies out for some time now. CHIPS technology was introduced not so long ago, but still has "little" adoption (currently "only" available in Blink-based or Gecko-based browsers). Prior to Firefox 141, it was temporarily disabled due to web compatibility issues. Starting with Firefox 141, the feature is fully enabled. The feature is also implemented in [[https://webkit.org/blog/16574/webkit-features-in-safari-18-4/|Safari 18.4 (released recently)]]. CHIPS implementation introduces a new Cookie parameter named //Partitioned//, which should be applied during //Secure// context. This RFC proposes two groups of changes: 1. Adding a new option "partitioned" for setcookie() and setrawcookie() functions. true, 'partitioned' => true]); ?> Notably, only the array overload of these functions is affected. This is in a similar vain to the recent ''samesite'' addition that also was only added to the array overload. 2. Add support for partitioned session cookies. This means that session_set_cookie_params(), session_get_cookie_params(), and session_start() will receive support for partitioned cookies. Currently, frameworks and applications have to work around not having this option by manually setting a header, which is cumbersome. This feature was requested via https://github.com/php/php-src/issues/12646, and has seen some activity and workarounds being posted. ===== Proposal ===== Extend setcookie() and setrawcookie() functions and make them able to accept one more option named "partitioned" to control CHIPS behavior. Using "partitioned" without setting "secure" will throw a ValueError. Extend session_start() options with "cookie_partitioned", and session_set_cookie_params()'s array overload to support the "partitioned" key. Also update the returned array from session_get_cookie_params() to include the "partitioned" key with a boolean value. ==== Examples ==== Example 1: Regular CHIPS usage: true, "partitioned" => true]); // will result in headers: // Set-Cookie: name=value; secure; Partitioned ?> Example 2: Using "partitioned" without "secure" or with disabled "secure" option: true]); setcookie("name", "value", ["secure" => false, "partitioned" => true]); // Both raise a ValueError: // Uncaught ValueError: setcookie(): "partitioned" option cannot be used without "secure" option in ... ?> Example 3: Starting a session with partitioned cookies: true, "partitioned" => true]); session_start(); // will result in headers: // Set-Cookie: PHPSESSID=12345; path=/; secure; Partitioned ?> Example 4: Setting the session cookie settings and dumping those settings: true, "partitioned" => true ]); var_dump(session_get_cookie_params()); // will dump this array: // array(7) { // ["lifetime"]=> // int(0) // ["path"]=> // string(1) "/" // ["domain"]=> // string(0) "" // ["secure"]=> // bool(true) // ["partitioned"]=> // bool(true) // ["httponly"]=> // bool(false) // ["samesite"]=> // string(0) "" // } ?> Example 5: Configuring the session with partitioned, but not secure: false, "cookie_partitioned" => true])); // bool(false) // Warning: session_start(): Partitioned session cookie cannot be used without also configuring it as secure in ... ?> The reason we defer the check until the session is started, is because any combination of ini_set(), session_start(), session_set_cookie_params() can set //some// cookie settings. ===== Backward Incompatible Changes ===== No breaking changes. ===== Proposed PHP Version(s) ===== PHP 8.5 ===== RFC Impact ===== ==== To the Ecosystem ==== No effects. ==== To Existing Extensions ==== - ext/standard, as the existing setcookie() and setrawcookie() PHP APIs are contained there. Furthermore, there is an internal API ''php_setcookie'' for C extensions that now gets an additional boolean argument ''partitioned''. - ext/session, as described above. ==== To SAPIs ==== An additional cookie parameter is introduced, but it has no direct API influence on the SAPI layer. ==== php.ini Defaults ==== The session cookie settings for session_start() and session_set_cookie_params() are stored in INI settings. These functions internally modify the session INI settings for the lifetime of the request. For example, using session_start(["cookie_secure" => true]) will set the ''session.cookie_secure'' setting to true. Likewise, we will add a ''session.cookie_partitioned'' boolean setting that defaults to false, but can be set via the above-mentioned functions. It is also possible to default this setting to true in the php.ini if one desires to do so. ===== Open Issues ===== No issues. ===== Future Scope ===== Currently, there is no future scope. Any CHIPS evolution steps will be made separately. ===== Voting Choices ===== Single voting widget that requires 2/3rd majority. * Yes * No ===== Patches and Tests ===== Implementation (patch+test): https://github.com/php/php-src/pull/12652 ===== Implementation ===== After the RFC is implemented, this section should contain: - the version(s) it was merged into - a link to the git commit(s) - a link to the PHP manual entry for the feature ===== References ===== CHIPS MDN: https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies ===== Rejected Features ===== None yet. ===== Changelog ===== Version 0.9.1: Extra clarifications on non-Blink browsers, thanks Claude! Version 0.9: First version.