55
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHPでSame-site cookie

Last updated at Posted at 2018-07-06

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にも反映されてません :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の設定が可能です。

55
39
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?