17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PHP】setcookieでPartitionedを発行したい場合はどうすればいいか

Last updated at Posted at 2024-01-15

サードパーティCookieについて

サードパーティCookieは2024年以降、基本的に禁止されます

この理由の大きなひとつが、サイトAとサイトBの情報を紐付けされてしまうことです。

01.jpg

※画像出典:Chrome 114 の新機能

tracking.coma.com上でのあなたの動きを監視することができますし、tracking.comb.com上でのあなたの動きを監視することができます。
そしてtracking.comは、a.comb.comの情報を紐付けることが可能です。

すなわち、多数のサイトで紐付けを行うことで、あなたの趣味嗜好思想信条が完全に把握されてしまうわけです。
FacebookやInstagramでは聖人面しておきながら裏ではあんなサイトやこんなサイトを見ているんだ、みたいなことが現在のCookieの仕組みでは可能です。
可能ですというかおそらく実際やっているでしょう。

逆に言うと、サイトを横断して情報収集ができないのであればサードパーティCookieを発行できても問題ないわけです。
という発想で作られたのがCookies Having Independent Partitioned State、通称CHIPSという仕組みです。

02.png

tracking.coma.com上でのあなたの動きを監視することができますし、tracking.comb.com上でのあなたの動きを監視することができます。
しかしtracking.comは、a.comb.comの情報を紐付けることはできません。

めでたしめでたし。

使い方としてはcookieにPartitioned属性を発行するだけであり、簡単に切り替えることができます。

setcookieの問題点

ということでPHPでもCHIPSに対応したいですね。
ところが実はそう素直にはいきません。

以下はsetcookie関数のシグネチャです。

setcookie(string $name, string $value = "", array $options = []): bool

// 古い書き方
setcookie(
    string $name,
    string $value = "",
    int $expires_or_options = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool

元々は引数を個々に受け取るシグネチャだけでしたが、引数が多くなりすぎてしまったためPHP7.3において配列で受け取るオプションが追加されたという歴史があります。
また複数のシグネチャを持つ関数は徐々に整理されつつあるため、古い書き方は今後使用できなくなる可能性があります。
従って、今後は配列で渡すほうを使うようにしましょう。

さてこの$options引数ですが、ひとつ問題があります。
なにかっつーと対応している属性以外受け取ってくれないんだなこれが。

setcookie('name', 'value', ['secure'=>true, 'Partitioned'=>true]);

03.png

Partitionedなんて知らねーよのFatal errorが出ます。

なんで。

PHP8.3時点では$optionsに渡せることのできる属性はexpirespathdomainsecurehttponlysamesiteだけであり、それ以外の値を渡すことはできません。

なんで。

setcookieでPartitionedを渡せるようにするプルリクエスト

ということでPartitionedを渡せるようにするプルリクエストが投げられていました。

メーリングリストにも投稿がありますが、特に大きな反応もないまま埋もれているようです。

このプルリクは、おそらくRFCを通さずマージされるんじゃないかなと思います。
というかこの程度でRFCとかいらんやろ。

と言いたいところですがかつてSameSiteが追加されたときはわざわざRFCが立ってたので、もしかしたらRFC経由になるかもしれません。
こんなんそのまま通してええやろ…

旧バージョンでもPartitionedを発行したいんだけど

この対応によって、今後のバージョンでPartitionedなCookieが発行できるようになる予定です。

しかし、諸事情でサーバの更新ができない、あるいは今すぐPartitionedを発行したいという場合はどうすればいいのでしょうか。

$options = [
    'expires' => 0,
    'path' => '/',
    'samesite' => 'strict; Partitioned; Priority=Low; hoge=fuga',
    'secure' => true,
    'httponly' => true,
];
setcookie('name', 'value', $options);

04.png

マジかよ…

正直バグというか脆弱性なのでは?という挙動ですが、現状では関数が対応していない属性のCookieを発行するにはこんなことをしなければなりません。
これずっと前から既知の動作なので、このような場合のためにあえて潰さずに残しているのかもしれませんね。

あとMixiが公式にこの方法を案内しているのはちょっと笑う。

感想

というかむしろ、そもそも渡せる引数の制限を外してくれんかね。
今の仕様だと、今後もキーが増えるたびに毎回対応する必要があるわけで、それなら最初から好きな値を渡せるようにしておいた方がいいと思うのだが。

実際既に、SamePartyPriorityといった一部ブラウザの独自属性には、まともな方法では対応できず、バグっぽい怪しい方法を使わざるを得ません。
まあ独自実装など知ったこっちゃねえという話ではあるのですが、実際そう言われても困ることもあるので、ここはまあどうにかしてほしいところですね。

17
6
0

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
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?