Cookie Prefix に __Http- と __Host-Http- がきた

こんにちは、エンジニアのあざらし 🦭 です。

少し前の話になりますが、Google Chrome 140 (stable) が 2025/09/03 (JST) にリリースされました。スクロールや View Transition 周りなど、気になる変更も多くありましたが、本記事ではその中から Cookie の新しい prefix __Http-, __Host-Http- に焦点を当てて紹介します。

developer.chrome.com

注意: リリースノートでは __HostHttp- とハイフンが抜けている記述になっていますが、2025/09 において正しくは __Host-Http- です。

Cookie Prefix とは、特定の prefix のついたクッキーが特定の属性(e.g. Secure, HttpOnly, ...)を持っていることを保証する仕様です。具体的には UA がそのクッキーの受信時(Set-Cookie など)に検証し、要件を満たしていない場合は保存しない(結果としてサーバにも送られない)というものです。

従来、サーバが UA から送られる Cookie の属性を知ることはできないという問題がありましたが、Prefix の存在により(一部の)属性が保証されることで、単なるつけ忘れや経路上・サブドメイン間の攻撃などによる意図しない挙動を防ぐことができ、多層防御の一つとしてセッションの安全性を高めることができます。

現在は __Secure-__Host- prefix の 2 つが仕様として定義されています。

__Secure- は Secure 属性が付与されていること、つまり HTTPS 文脈でしか送信されないことを保証します。

__Host- は Secure 属性に加えて Domain 未指定かつ Path=/ であること、つまり結果的に HTTPS 文脈でしか送信されないことと、セットしたホストにしか送信されないこと、またパス違いの同名クッキーに上書きされないことを保証します。

__Http-__Host-Http- prefix

そして今回、新たに __Http-__Host-Http- が Chrome 140 (stable) で(提案は以前からされていましたが)実装されました。

計 4 つの prefix を表にまとめるとこのような形になります。

Prefix 必須属性
__Secure- Secure
__Host- Secure
Domain 未指定
Path=/
__Http- Secure
HttpOnly
__Host-Http- Secure
Domain 未指定
Path=/
HttpOnly

__Http- の要件は SecureHttpOnly 属性が付与されていることです。つまり HTTPS 文脈でしか参照できないことと、クライアントサイド JS から定義されたり参照されたりしないこと(Set-Cookie フィールドによって定義されたこと)を保証することで、XSS などの攻撃による窃取のリスクを低減します。

__Host-Http-__Host- の要件 (Secure + Path=/ + Domain 未指定) と __Http- の要件 (HttpOnly) を組み合わせたものです。

__Host-Http- を付与するモチベーションとして、例えばセッション ID など常に Set-Cookie でしか定義されないクッキーが、 XSS 攻撃や悪意のあるブラウザ拡張機能などから影響を受けていないことをサーバ側で見分けやすくなるという点が挙げられます。

エコシステムの状況

Firefox も Safari もこの仕様についてはそれぞれ positive / support となっています。

Firefox では当初の古い名前(後述します)ではありますが 2025/08 時点ですでにリリースされています。

https://caniuse.com/mdn-http_headers_set-cookie_http_host-http_prefixes

ブラウザーの互換性
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#browser_compatibility

prefix の組み合わせに関する議論

ここからは、今回の prefix の ship に至るまでの流れの中で個人的に面白いと感じた議論を紹介します。

主に prefix の組み合わせに関するもので、今回追加された__Http-と既存の__Host-の要件を満たしたクッキーを表現する方法についての議論が盛り上がって(?)いました。

最終的には __Host-Http- という固定文字列を追加する方針に決定しましたが、議論の過程では以下のような案が検討されていたのでそれぞれ軽く紹介します。

  • 順不同で連結できるようにする案
  • 別の(ヘッダ)フィールドで属性を返すようにする案
  • 固定文字列で__HostHttp-を追加する案

順不同で連結できるようにする案

まずは「将来的に属性が増えた場合、どのように組み合わせを表現するか」という話です。

https://github.com/httpwg/http-extensions/issues/3111#issuecomment-2986241396

prefix でフラグを表現する方式では、順不同をどう扱うかという問題があります。

例えば CHIPS の Partitioned 属性に関連して __Unpartitioned- prefix が追加された場合、 __Host-Unpartitioned-__Host-Http-Unpartitioned- といった複合形に加え、並び順の違いを考慮した __Host-Unpartitioned-Http- のようなバリエーションも考えられます。

これらを網羅的に固定文字列として定義するのは現実的ではないため、出た解決策が「順不同で連結できるようにしてサーバ側でパースする」という案です。これはつまりサーバ側で __ で始まるクッキー名を /__(\w+-)+/ というパターンとしてパースすることで任意の prefix を任意の順番で扱うというものになります。

実際、今後さらに prefix が増えた場合、(__Host-Http- がすでに存在する前提である以上は)この方法が最も自然かつ柔軟な解決策であるように思えます。

しかしこれについてはパーサの実装が必要になる点に加えて、そもそも今後 prefix が増えるかどうかも不明であるという指摘もあり、最終的に合意には至りませんでした。

(そもそも現時点で prefix として定義する可能性が残っているのは Partitioned 属性くらいですが、例示で示唆されていた __Unpartitioned- についても既にある他の prefix とは性質が異なり本当に必要なのか、という議論が提起されていました。長くなるので取り上げませんが、こちらも興味深い議論です。 https://lists.w3.org/Archives/Public/ietf-http-wg/2025AprJun/0193.html

別の(ヘッダ)フィールドで属性を返すようにする案

組み合わせをパースする議論以前に、そもそも Cookie の属性を表現するために prefix を使うこと自体が問題である、という指摘もありました。

例えばサーバ側が prefix の担保を UA 側に強制することができない(実質サーバは担保できない)ことなどが理由として挙げられており、この状況で prefix の組み合わせのパース方法について議論するのは得策ではないというものです。(エレガントな解決策ではない、というコメントもありました。)

https://github.com/httpwg/http-extensions/issues/3111#issuecomment-2986241396

指摘の中で、例えば Cookie フィールドの中で属性を担保するのではなく別のフィールドでそれぞれのクッキーに対応する属性を返すようにすれば良いのではないかという提案がなされていました。

例えば以下のような形です。

Cookie: session_id=abc123;
Cookie-Attributes: session_id="Secure; HttpOnly; Path=/; SameSite=Strict"

これのメリットは Cookie フィールドにおいて後方互換性を保ちつつ、新フィールドの存在によってサーバ側が UA の対応状況を知ることができるという点が挙げられています(Feature Detection のような形ですね)。

Prefix の場合、全ての UA が対応しているという保証がない以上は__Host-Http-を見ても確信できない、という問題がありますが、別フィールドであれば少なくとも UA が対応済みなのかどうかを見分けることができます。

またそもそも真偽値のフラグではなく属性を網羅的に列挙でき、将来の仕様変更にも柔軟に対応できるという点もあります。

しかしこれも、(前述の通り)今後の prefix 追加の可能性が不明であることや、そもそもこれ以上 prefix を増やすべきではないという指摘もあり、最終的に合意には至りませんでした。

固定文字列で__HostHttp-を追加する案

最終的に、一旦は固定文字列で __HostHttp- を追加する案に落ち着きます。(__Host_Http-も一瞬俎上に載りましたが、特に議論もなく __HostHttp- に決まったように見えます。)

実際に 2025/06 の Chrome 140 (beta) ではこの __HostHttp- で実装されました。

しかし後方互換性の問題があり、2025/08 に __Host-Http- への変更が提案されました。

https://github.com/httpwg/http-extensions/pull/3153

この問題は __Host- という prefix が存在するのに、 __HostHttp- では __Host- とは異なる prefix として扱われてしまうため、未対応の UA では HttpOnly 属性どころか Host 要件すら担保されない、というものです。(あるいは未対応の UA を Client Hints や User-Agent で見分ける必要がある。)

そして今回、 __Http- とともに(後方互換性のある) __Host-Http- が 2025/09 に Chrome 140 (stable) で実装されたという流れになります。

https://source.chromium.org/chromium/chromium/src/+/main:net/cookies/cookie_util.cc;drc=af9577ae69c34a38f5a02903bd7e21b71b842b7f;l=766?q=kPrefixCookieHostHttp&ss=chromium%2Fchromium%2Fsrc

おわりに

Cookie Prefix とそれぞれの prefix、そして prefix 追加に至るまでの議論について軽く見てきました。

後方互換性を保つ形で __Host-Http- が採用されたことで実務的にも導入のハードルが下がりましたし最近では HttpOnly でないクッキーを使うケースもほぼないと思うので、例えばセッション ID など重要なクッキーには __Host- の代わりに __Host-Http- を付与しておく のが良さそうです。

また、今後 prefix の追加があれば複数 prefix の組み合わせの議論が再開されることになると思うのでそちらにも注目ですね。

おわり


参考資料