先日某所の勉強会でCookieのセキュリティ周りの話をしていたのですが、その中で自分のDomain属性の理解が不十分だということに気付きました。
Cookieのセキュリティ関係の属性としては、Domain
, Secure
, HttpOnly
などがあります。Secure
は設定されていればHTTPSで通信していなければCookieを送信しない。HttpOnly
はJavaScriptからCookieにアクセスさせない、とどちらもわかりやすい機能ですが、Domain
については割と複雑です。
複雑だからといって理解が不十分なままにしてはおけない、ということで調べてまとめてみました。
この記事ではサーバからクライアントへのSet-Cookie
ヘッダによるCookieの送信を「(Cookieの)設定」と、クライアントからサーバへのCookie
ヘッダによるCookieの送信を「(Cookieの)送信」と呼びます。
Domain属性は、Cookie送信時にどう働くか
順番としてはサーバからクライアントにCookieを設定した上で、クライアントからサーバに設定されたCookieを送信、という流れですが、Cookie送信時の挙動の方がわかりやすいため、まずこちらから説明します。
これは簡単で、送信時のDomain属性の働きは「設定された値と送信先のサーバのドメインがマッチするときにだけCookieを送信する」となります。
ただしマッチする方法には完全一致と後方一致の2パターンあります。完全一致は設定時にDomain属性を指定しなかった場合に、設定したサーバのドメインで完全一致になり、指定した場合は常に後方一致になります。
Domain属性の値 | 送信先ドメイン | 送信 |
---|---|---|
未指定(example.com) | example.com | される |
未指定(example.com) | foo.example.com | されない |
未指定(foo.example.com) | example.com | されない |
未指定(foo.example.com) | foo.example.com | される |
example.com | example.com | される |
example.com | foo.example.com | される |
foo.example.com | example.com | されない |
foo.example.com | foo.example.com | される |
なお後方一致は階層的なものなので、example.com
を指定した場合に、abcdexample.com
に送信されることはありません。
Domain属性の設定に制限はあるのか
ご存知の通り、悪意のあるサーバから攻撃対象のサーバに送信されるCookieを自由に設定できてしまうと、セッション固定攻撃の要因になってしまい危険です。それを防ぐためのメカニズムはどうなっているのでしょうか。
設定できるDomain属性には制限があります。制限に反するDomain属性を設定しようとしても、ブラウザに拒否されて設定できません。ブラウザによってはコンソールログなどにCookieを拒否した旨のメッセージが出たりします。
では具体的にどういう制限があるのか。Cookieを設定するサーバ自身のドメインか、そのドメインより上位の階層のドメインのみ設定できます。
Cookieを設定するサーバのドメイン | Domain属性に設定するドメイン | 設定の可否 |
---|---|---|
example.com | example.com | 可 |
example.com | foo.example.com | 否 |
foo.example.com | example.com | 可 |
foo.example.com | foo.example.com | 可 |
bar.example.com | foo.example.com | 否 |
abc.example | example.com | 否 |
直感的でないのは、自身より下位の階層(example.com
の場合のfoo.example.com
)のドメインを設定できないことです。また、兄弟関係にある階層のドメインも設定できません。ただしこれらのパターンに関しては、どちらもexample.com
を設定すれば送信される対象にはなります。
ということで、CookieのDomain属性は安全です……あれ?
おそらく気付かれたと思うのですが、example.com
から見てcom
は上位の階層のドメインです。ではexample.com
からcom
をDomain属性に設定して、.com
のすべてのドメインに向けたCookieを設定できてしまうのでしょうか。
現在の仕様(RFC 6265)では、これは制限されています。ブラウザは、com
のような公共のドメイン接尾辞(public suffix)1を受け付けないように決められています。2
公共のドメイン接尾辞のリストは、Public Suffix Listで公開されています。
このようにリストの形になっているのは、どのレベルのドメインの所有者を同一と見做すかのルールが存在しないからでしょう。com
のようなトップレベルドメインのサブドメインはおそらくそれぞれ別の所有者のものと考えられそうですが、co.jp
やne.jp
のようなセカンドレベルドメインの場合は判断できません。co.jp
やne.jp
はサブドメインに別々の所有者がいる公共のドメインですが、jprs.jp
は株式会社日本レジストリサービスの所有するドメインで、おそらくそのサブドメインのすべても同社が所有しています。
公共のドメイン接尾辞のリストがあるから安心、かというと……
じつは安全でない場合がいくつかあるようです。
Cookie Monster問題
公共のドメイン接尾辞のリストは、割と最近(2008年)に作成されたもので、また現在ある程度有効なCookie仕様であるRFC 6265もさらに後の2011年に初めて公開されたものです。
それ以前はおそらくブラウザごとに独自の対応をしていた面が強いと思われ、実際co.jp
のようなドメインをDomain属性に設定できるという話さえありました。
このような、公共のドメインをDomain属性に設定できてしまう脆弱性をCookie Monsterと言うようです。この脆弱性は2021年現在も部分的に残っているようです。
参考:
公共のドメイン接尾辞のリストの開始時期は以下のPDFから。
Public Suffix Listとその問題点(PDF)
Cookie Monster脆弱性については体系的に学ぶ 安全なWebアプリケーションの作り方の初版・第2版等から。
実質的に公共のドメインになっている、レンタルサーバ等のドメイン
私の愛用しているさくらのレンタルサーバでは、利用者に好きな文字列.sakura.ne.jp
というサブドメインを用意してくれます。
この場合のsakura.ne.jp
は公共のドメインではなく、そのためサブドメインからsakura.ne.jp
のCookieが設定できるようです。
参考:
利用者にサブドメインを提供するレンタルサーバでのセッション固定攻撃の可能性について。
セッションフィクセイション脆弱性の影響を受けやすいサイトとは | 徳丸浩の日記
ではどうするか
昔と比べれば外部からのCookieの設定は難しくなってはいるようですが、それでもまだしばらくはCookieは外部から設定される前提でいた方がよさそうです。
また外部からのCookieの設定によるセッション固定攻撃に対しては、「体系的に学ぶ 安全なWebアプリケーションの作り方」やIPAの安全なウェブサイトの作り方にあるように、ログイン時に常にセッションIDを再生成しましょう。
おまけ: 3rd party cookieとはなんなのか
Cookieの制限について考えていると、プライバシー方面でよく耳にする3rd party cookieとはなんなのか、という疑問が湧いてきました。
ここまで書いてきたように、Cookieは細かい問題はあるものの、概ね設定できる送信先ドメインは制限されています。
今回の記事の主題ではないため簡単に説明すると、3rd party cookieとは、訪問したサイトから読み込まれた外部の画像やJavaScript経由で設定される、外部のドメインに送信されるCookie, ということのようです。
example.com
内のページにhttps://adserver.example/ad.jpg
のような画像への参照がある場合、意図せずadserver.example
からCookieを設定されてしまいます。これを3rd party cookieと呼ぶようです。
セキュリティ的に問題になることはないですが、この手法によるユーザの追跡がプライバシー方面ではよく問題になっています。
参考:
3rd party cookieとはなにかについて。
7.1. 第三者主体によるクッキー / Cookies: HTTP State Management Mechanism (日本語訳)
参考
Cookieの仕様(RFC)の日本語訳。Cookieは長らく仕様ベースで実装されていなかったようですが、このRFC以後はある程度仕様ベースで実装されていきそうです。
Cookies: HTTP State Management Mechanism (日本語訳)
この記事のライセンス
この文書はCC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)で公開します。