Firefox 2.0 ではおかしなクッキーの動作が一部だけ直っている模様

Security 11月 8, 2006
(Last Updated On: 2006年11月9日)

備考:名無しさんの指摘でタイトルを変更、一部本文を修正しました。(IEとFFの立場を入れ替えました)

少なくとも2006年1月ころのMozilla系ブラウザには簡単に設定できるべきでないクッキーが設定できてしまう問題がありました。最悪なのはco.jp等、ccTLDの属性ドメインに対してクッキーが設定できてしまう動作ですが、手元のFirefox 2.0で試したところHTTPのSet-Cookieヘッダではco.jpには設定できなくなっています。しかし、この修正が中途半端でJavaScriptからdocument.cookieにco.jpにクッキーを設定できてしまいます。(名無しさん、情報ありがとうございます)

example.co.jpとwww.example.co.jpに同じ名前のクッキーを設定するとexample.co.jpのクッキーが返ってきます。下位ドメインによるクッキーの上書きが出来ないのは従来どおりのようです。(複数のクッキー値がドメイン毎に設定される)明示的にwww.example.co.jpドメインからexample.co.jpドメインのクッキーを上書き/削除できるのも従来どおりのようです。host1.example.jpからhost2.example.jpのクッキーが設定できるのも従来どおりのようです。

# 上位ドメインのクッキーを設定できるのに同じレベルのドメイン
# クッキーが設定できなくてもあまり意味が無いです。
# PHPユーザの場合、my-server.hosting.jpの様なドメインを
# 持つサイトの場合、余計なクッキーの削除と外部からのセッ
# ションIDを受け入れないように注意が必要ということ意味し
# ます。

KHTML(Safari、Konqurer)は2004年くらいにこの問題(ccTLDのクッキー)には対応済みと思います。

IE6/7では今のFFと同じでほかの上位ドメイン等のクッキーの上書き/削除は同じ動作をするようです。

もう少し調査が必要ですが、とりあえずccTLDに関しては最新ブラウザを使っていれば大丈夫なようです。まだまだ最新ブラウザでも安心できないようです。

参考:
Multiple Browser Cookie Injection Vulnerabilities
Client Side State – HTTP Cookies
HTTP State Management Mechanism (RFC2109)
HTTP State Management Mechanism (RFC2965)

RFC2109(Cookie1)はNetscapeクッキーの後追い標準なので仕方ないですが

* A Set-Cookie from request-host y.x.foo.com for Domain=.foo.com
would be rejected, because H is y.x and contains a dot.

* A Set-Cookie from request-host x.foo.com for Domain=.foo.com would
be accepted.

* A Set-Cookie with Domain=.com or Domain=.com., will always be
rejected, because there is no embedded dot.

* A Set-Cookie with Domain=ajax.com will be rejected because the
value for Domain does not begin with a dot.

と親ドメインへのクッキー設定は標準です。example.co.jpでco.jpにクッキーを設定できないとは書いてありません。

Cookie1の定義では

cookie = “Cookie:” cookie-version
1*((“;” | “,”) cookie-value)
cookie-value = NAME “=” VALUE [“;” path] [“;” domain]
cookie-version = “$Version” “=” value
NAME = attr
VALUE = value
path = “$Path” “=” value
domain = “$Domain” “=” value

とパスとドメイン情報を送信することになっていますが、IEもFirefoxも

Cookie: var=FOO;var=BAR\r\n

という感じでパスもドメイン情報も無しで、複数の値を送ってきます。IE,Firefox共に先に親ドメインの値を設定するようになっているようです。

パス設定が行われている場合は最適なクッキーから順番に書くようになっている

If multiple cookies satisfy the criteria above, they are ordered in
the Cookie header such that those with more specific Path attributes
precede those with less specific.

のですが、ドメインの方は

Ordering with respect to other attributes (e.g., Domain) is unspecified.

と未指定です。IE,Firefox共にここはRFC仕様と同じでパスが指定されているときは一致度が高いクッキーから順番に返し、ドメインは上位ドメインから順番に返してきます。

PHPの場合、先に設定された値が$_COOKIEに入るので複数のPATHが指定された場合は期待通りの動作をしますが、複数のDOMAINが指定された場合はホストのクッキーではなくドメインのクッキーが使われてしまいます。

このため余計なクッキーが設定されないようにクッキーを設定する場合、setcookie/setrawcookie関数のラッパーを書いてドメインのクッキーを削除してからクッキーを設定するようにしないと問題となる場合があります。

# セッションIDが設定されている事によるDoSやSessionIDの固定化を
# 防ぐにはsetcookie(‘PHPSESSID’,”,0,path,domain);
# 等とします。pathはパス、domainはドメインを指定する文字列。

どちらにしてもRFCに記述されている$Version, $Path, $Domainは無視しているのでIE,Firefox共にいわゆるOldクライアントとして動作していることになります。IE, Firefox共にSet-Cookie2:ヘッダは無視しています。Web黎明期の仕様はあまりセキュリティを考慮しておらず今でもその仕様に従わざるを得ないのは仕方ないです。下を見て比べても有意義ではありませんがSMTPよりはマシかな…

しかし、ドメイン指定で複数の値がある場合にホストと完全に一致したクッキーから順番に返してこないのはNetscapeの動作がそうなっていたからなのでしょう。コーディングした人は「順番なんてどちらでも良いや」くらいに思っていたと推測できます。(それともNetscapeクッキーの仕様では親ドメインのクッキー優先?)ドメイン、パスを明記するRFCのクッキー仕様通りならサーバ側で意図通りの値のみを使用する事も可能ですが、IE,Firefox共にパスやドメイン情報を返してきません。複数のパス、ドメインに一致するクッキーは

Cookie: var=v1;var=v2;var=v3;var=v4;

と、どれがどれだか全く判らない状態で値を返してきます。(パスだけ設定されている場合はパスの一致度が高い物から先に値が設定されます)当然ですがこの動作だとパスとドメインで一致度が高いクッキー値をサーバ側で判別不可能です… 自衛策としては上位ドメインで設定されたクッキーを明示的に削除するしかありません…

投稿者: yohgaki