Mac版IEのCookieのpathのセキュリティバグ

'01.4.7 ('03.7.2更新)

Cookieをあれこれ実験しているうちに、Mac版IE (Internet Explorer) のセキュリティバグを発見してしまいました。確認したところIE3からあって、開発中止決定後のIE5.2.3でも直りませんでした。わたしが発見したのは2000年の6月ですが、知る人ぞ知るバグだったようです。MacのIEユーザーはもちろん、CGI設置者も知っていないと困りますね。

  1. Mac版IEのバグ
  2. あなたのCookieは大丈夫?
  3. ユーザーの対策
  4. CGI制作、改造時の対策
  5. Netscape Navigatorの癖

Mac版IEのバグ

pathを指定しないとCookieをセットしたファイル(CGI)のあるディレクトリの指定になるのがデフォルトのはずですが、Mac版IEでは「/」になってしまいます。たとえば、
http://hpcgi1.nifty.com/foo/hoge.cgi
でセットしても
http://hpcgi1.nifty.com/
の中のどのメンバーのファイル (CGI) にもCookieを送ってしまいます。Cookieにパスワードを記録してある場合などきわめて危険です。

CGIプログラム制作者が、「path=/foo/」と明示的にpathを指定すれば問題ないのですが、普通わざわざpathの指定をしませんから、独自ドメインでない限り、世間の掲示版とかCGIプログラムの殆どはこのセキュリティバグに引っかかります。というかIEが悪いのですが。いままでIE開発者に誰も知らせなかったのでしょうか。というわけでMicrosoftへはとっくに報告済みですが、ついに開発中止決定後に出た5.2.3 (for OS X) になっても直りませんでした。合掌。

あなたのCookieは大丈夫?

もしMac版IEを使っているなら、クッキー表示CGIを試してみましょう。あなたのブラウザから http://hpcgi1.nifty.com/glass/cookie/ (@niftyのCGI) に送られてくるCookieを表示します。

http://hpcgi1.nifty.com/ に置いてある誰かのCGIでCookieを使ったことがあれば、漏れている可能性が高いです。もちろん、他のサーバで漏れているCookieまでは分かりませんが。

バナー広告にありがちな、すべてのサーバに送られるCookieはバグとは関係ありません。

ユーザーの対策

セキュリティバグといっても、原理のよく分からない人でも無闇に怖がることはありません。対処方法はあります。危ないのはプロバイダのサーバを間借しているようなサイトで、独自ドメインのサイトなら情報が漏れる心配はありません。

まずは初期設定のCookieで各Cookieを確認します。表示して「サーバー:」が「hpcgi1.nifty.com」等の多数のユーザーが使うドメインで、「パス:」が「/」になっているものは削除します。面倒なら一度Cookie全部消してしまう手もありますね。それからは、以下の方法どれかを選びます。

  1. パスワードや削除キー等他人に見られて危なそうな項目には記入しない。危ないものを入力しなければ何も問題ないわけです。
  2. 記入は行うが、送信後すぐに該当するCookieを削除する。
  3. Cookieを使わない設定にできる掲示版等ならば、使わないで書き込む。
  4. 初期設定のCookieで「Cookieを受信したとき: 常に警告する」にしておいて、危なそうなCookieは受け入れない。意外にCookieを使うサイトが多いことに驚くでしょう。自分から個人情報等を書かない限り殆ど問題ないCookieです。
  5. いつもCookieをオフにしておいて、必要なCookieの時だけオンにする。ショッピングサイトでの買い物かごとかCookieが必須の場合もありますね。(初期設定でオフにするとそれまでのCookieがすべて消えます)
  6. Safari (OS X10.2以降)MozillaNetscapeiCabOperaOmniWeb (OS X版だけ) 等他のブラウザを使う。
  7. 対処済みIEが出るのを待つ。う〜ん。もうダメ。

そうそう、NetscapeだとCookieをオフにしてもブラウザを終了する前に戻せば復活してしまいますが、IEは一度オフにするとそれまでのCookieが全部消えます。IEのCookieは、システムフォルダの初期設定のInternet Preferencesファイルに、他のインターネット設定項目と一緒に保存されますから、バックアップも可能です。

CGI制作、改造時の対策

設置するアカウントに合わせてpathを書いてもいいのですが、汎用性を持たせるなら、$ENV{SCRIPT_NAME}からpathを取得できます。簡単ですね。

$cookie_path = $ENV{SCRIPT_NAME};
$cookie_path =~ s/[^\/]*$//;

で、Cookieの部分はこんな具合です。「Set-Cookie:」が複数あるならすべてにpathを書き加えます。「expires」が無いCookieにもpathは必要です。

print "Set-Cookie: HOGE=$cookie; expires=$gmt\n";

         ↓ ↓ ↓

print "Set-Cookie: HOGE=$cookie; expires=$gmt; path=$cookie_path\n";

Netscape Navigatorの癖

NetscapeのデフォルトのCookieは、path=/fooなんですね。
http://hoge.com/foo/hoge.cgi
でセットしてpathを指定しない場合IE for Windowsでは、
path=/foo/
Netscapeでは、
path=/foo
となります。最後に「/」が無い場合、
http://hoge.com/foo/
http://hoge.com/foo_ber/
http://hoge.com/foo.cgi
等のfoo以下がなんであってもマッチします。foo1とfoo2と二つ以上のディレクトリで使いたい場合に便利ですが、@niftyなどはアカウント直下にCGIを設置可能ですから、fooさんのCookieがfoo_berさんに読まれてしまうことにもなりますね。ちょっと危ないです。

なぜNetscapeのデフォルトがそうなっているか謎です。これはNetscapeのバグではなく仕様なのですが、気を着けないとセキュリティホールになります。というわけで、ここでもpathの必要性が出てきます。

 
参考:
Cookieの規格
Client Side State - HTTP Cookies