Skip to content

Add encrypted cookies with key rotation - #9

Closed
TomK wants to merge 1 commit into
masterfrom
encrypted-cookies
Closed

TomK wants to merge 1 commit into
masterfrom
encrypted-cookies

Conversation

@TomK

@TomK TomK commented Sep 29, 2026

Copy link
Copy Markdown
Member

Adds EncryptedCookieHandler, which encrypts cookie values through the CookieJar handler chain:

$jar->addHandler(new EncryptedCookieHandler(Encrypter::fromConfig($config), ['plain-text-cookie']));

Encryption\Encrypter uses XChaCha20-Poly1305 via ext-sodium (or paragonie/sodium_compat, both suggested, not required). security.encryption_key can be a list: the first key encrypts and every key decrypts, so a key can be rotated without signing everyone out. Payloads match cubex/framework 2.7, so apps on either can share cookies with the same keys.

A cookie that fails to decrypt is left out of the jar rather than read as an empty string. To support that, a handler can now throw InvalidCookieException from decodeValue(), and hydrate() drops that cookie.

Test plan

PHPUnit passes on PHP 8.2 and 8.5 (75 tests). New tests cover round trips through a request and response, decrypting with a previous key, dropping forged and retired-key cookies, plain-text exclusions, and the encrypter's tamper, malformed-payload and key-validation cases.

🤖 Generated with Claude Code

EncryptedCookieHandler encrypts cookie values with Encryption\Encrypter:
XChaCha20-Poly1305 via ext-sodium, with a list of keys where the first
encrypts and every key decrypts, so a key can be rotated without
invalidating existing cookies at once. Payloads match cubex/framework
2.7, so either can read the other's cookies with the same keys.

A handler can now reject a request cookie by throwing
InvalidCookieException, and the jar leaves that cookie out. A cookie
that fails to decrypt is dropped rather than read as an empty value.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@TomK

TomK commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

Closing: no Cubex 4 app uses encrypted cookies today. If one needs them, the encrypter belongs in its own package (e.g. packaged/encrypt) alongside a cookie handler, with only the InvalidCookieException hook here. The code stays on the encrypted-cookies branch.

@TomK TomK closed this Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant