Cookies

Cookies, Encryption, and Queued Cookies

A /prefs route returns response('saved')->cookie('theme', 'dark', 60) (minutes) and calls Cookie::queue('currency', 'EUR', 60 * 24 * 30), which works anywhere because AddQueuedCookiesToResponse attaches queued cookies to the response. /prefs/read returns $request->cookie() for both:

Encrypted cookies, a forged plain cookie, and a Crypt round tripShell
curl -si -c jar $B/prefs | grep -i '^set-cookie: [tc]' \
  | sed -E 's/(=eyJ[^;]{6})[^;]*/\1.../; s/ expires=[^;]*;//'
curl -s -b jar $B/prefs/read; echo
curl -s -b 'theme=dark' $B/prefs/read; echo
awk '$6 == "theme" {print $7}' jar | sed 's/%3D/=/g' | base64 -d | jq -c 'map_values(.[0:12])'
php artisan tinker --execute "echo Crypt::decryptString(Crypt::encryptString('BK-PHP-01'));"
Output
Set-Cookie: theme=eyJpdiI6I...; Max-Age=3600; path=/; httponly; samesite=lax
Set-Cookie: currency=eyJpdiI6I...; Max-Age=2592000; path=/; httponly; samesite=lax
{"theme":"dark","currency":"EUR"}
{"theme":null,"currency":null}
{"iv":"FK51kVRJCvF+","value":"qG2/Ic730dI9","mac":"19b77729ed7b","tag":""}
BK-PHP-01

EncryptCookies made each value a base64 JSON envelope: a random IV, AES-256-CBC ciphertext and an HMAC-SHA256 mac. The hand-written theme=dark failed the check and read as null, and so did a genuine currency value sent as theme, because Crypt::decryptString() on the jar's theme value gives 6bd8d39c...|dark: the prefix is hash_hmac('sha1', 'theme'.'v2', APP_KEY), binding the value to its name. Exempt cookies JavaScript must read with $middleware->encryptCookies(except: [...]), and keep the old key in APP_PREVIOUS_KEYS when you rotate APP_KEY.