2020年1月13日追記
SameSite cookieは2018年12月にリリースされたPHP7.3.0のsetcookie()
関数でサポートされました。
7.3.0未満のPHPやPSR-7レスポンスに対してSet-Cookie
ヘッダをを設定したい場合のためにbag2/cookieライブラリを開発しました。詳しくはPSR-7と生PHPに対応したSet-Cookieライブラリを作った - 超PHPerになろうをお読みください。
近年のCookieではSameSiteと呼ばれる新しい属性が提案されました。この記事では、この属性の効能や副作用については言及しません。 めんどくさいからね… Can I useによれば現時点で50%を切る程度の普及率ではありますが、非対応ブラウザ向けに利用しても属性が無視されるだけなので、利用開始しても、おそらく支障ありません。
PHPでの問題
PHPではCookieはsetcookie()
で発行します。問題は、この関数のインターフェイスです。
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = FALSE [, bool $httponly = FALSE ]]]]]] )
属性ごとに引数で渡すようになってるので、SameSite
が入る余地がないのです。
PHP 7.3での改善
PHPの機能追加提案PHP: rfc:same-site-cookieでは、今年中にリリースされるPHP 7.3で追加される予定です。この提案が興味深いのは、引数の数を増やすのではなく、オプション引数のための連想配列をひとつだけ受け取るだけになったことです。
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, array $options ]]] )
つまり、このようにCookieを設定できるようになります。
setcookie('hoge', 'fuga', 3600, [
'path' => '/',
'secure' => true,
'httponly' => true,
"samesite" => 'Strict',
]);
問題は、PHP 7.3のフィーチャーフリーズ予定日が近付いたのにPRがまだマージされてないことです。 (つまり、現在リリースされてるPHP 7.3.0 alpha 3にも反映されてません )
従来のPHPでのワークアラウンド
では、PHP7.3の世界に辿りつけないわれわれは、まだSameSiteの恩恵に与ることはできないのか?
上記のPRでおもしろい例が紹介されてました。
With PHP < 7.3 some people use a hack to add the samesite option (
path="xxx; samesite=..."
), but this doesn't work anymore in 7.3 ad the values are filtered. So we really need this to be implemented.
変な声が出ましたね… SameSiteが入る余地あったけど、これって一種のインジェクションなのでは?? まあこのダーティーハックはいままでのバージョンで動いてるから、正式対応する7.3でも動作保障しないといけないよね、みたいな提案です。
さておき、これを悪用するとPHP7.3未満でもSameSite
属性が設定できます。
setcookie('hoge', 'fuga', 3600, '/; SameSite=Strict', '', true, true);
セッションで利用する場合はsession_set_cookie_params()
とか、php.ini
とか、ini_set()
とか、PHP7以降ではsession_start()
でも設定できます。
まとめ
これは一本とられた。しかしながら、この仕様挙動を悪用すればSameSite
の設定が可能です。