PHP 8.6 mění tři výchozí hodnoty v konfiguraci session. Jsou to změny, které měly přijít už dávno, a klidně je můžete mít v produkci už nastavené ručně.
session.use_strict_mode: z 0 na 1
Bez strict módu PHP přijme jakékoliv ID session, které mu prohlížeč pošle, tedy i takové, které si vymyslel útočník. To je podstata útoku zvaného session fixation. Se zapnutým strict módem PHP neznámé ID zahodí a vygeneruje nové.
Bacha na jednu věc. Pokud sdílíte ID session mezi subdoménami, musíte na výchozí straně nejdřív zavolat session_write_close(). Vlastních session handlerů, které z validateId() vždycky vrací true, se změna netýká.
session.cookie_httponly: z 0 na 1
Atribut HttpOnly říká prohlížeči, aby cookie nevydal přes document.cookie. Žádný JavaScript se k ní tedy nedostane, ať už je vlastní, nebo podstrčený přes XSS.
Pokud hodnotu session cookie v JavaScriptu čtete, přestane to fungovat. Na CSRF token použijte samostatnou cookie.
session.cookie_samesite: z prázdné hodnoty na Lax
SameSite omezuje, kdy prohlížeč cookie pošle na cizí web. S hodnotou Lax ji pošle u požadavků ze stejného webu a u běžné navigace, ale už ne u cross-site odeslání formuláře nebo u podzdrojů. To docela zásadně omezuje CSRF.
Tohle je z celé trojice nejrizikovější změna. Pokud se vám na nějaký endpoint vrací POSTem cizí systém (typicky SP-initiated SAML SSO nebo platební brána), potřebujete pro něj výslovně nastavit SameSite=None se Secure:
<?php
session_set_cookie_params([
'samesite' => 'None',
'secure' => true,
]);
session_start();
Případně jde u starých hodnot zůstat, ale bral bych to spíš jako dočasné řešení, než si aplikaci projdete:
<?php
ini_set('session.use_strict_mode', '0');
ini_set('session.cookie_httponly', '0');
ini_set('session.cookie_samesite', '');
Všechna tři hlasování dopadla jednoznačně, tedy 27 : 0, 26 : 0 a 26 : 0. Doporučuju si to projít dřív, než na 8.6 přejdete, hlavně to SameSite.