PHP
HTTP
cookie

PHPでSame-site cookie

近年の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にも反映されてません :upside_down:)

従来のPHPでのワークアラウンド

では、PHP7.3の世界に辿りつけないわれわれは、まだSameSiteの恩恵に与ることはできないのか?

上記のPRでおもしろい例が紹介されてました。

With PHP < 7.3 some people use a hack to add the samesite option (path=

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の設定が可能です。