2004/11/11(木)Cookieあれこれ
2004/11/10 27:00
まずクッキーの仕様から。
HTTPヘッダに以下を書くことによってブラウザにクッキーを食わせる。
Set-cookie: 変数名=値 [; [変数名=値;] [expires=有効期限(GMT);] [path=URLパス;] [domain=サイトドメイン;] secure]
設定したクッキーはドメイン名とペアで記録される。ドメイン名とPathに該当するURLにリクエストを出す際に、ブラウザはHTTPリクエスト中に
Cookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...
を含める。この値は環境変数HTTP_COOKIEにセットされる。従って、expiresの値などはサーバ側から知ることは出来ない(多分)ということだ。
クッキーのセットに関して、デフォルト値と気をつけることをいくつか把握しておく必要がある。
・expires省略時はセッションを閉じるとcookieが消える
・path省略時は設定したページのフォルダ
・domain省略時は設定したページのドメイン
・pathに/を設定すると該当ドメインの全サイトに対してcookieが送られる。認証情報をcookieに入れる際には非常に危険
・secureはhttpsでないと意味がない
さて、cookieを用いて認証情報を管理する場合2通りが考えられる。
1.expires無指定で、パスワード入力から同一セッションでのみ管理者と認定
2.expiresに値を入れて、そのcookieを持つブラウザを管理者と認定する
多くのCGIで実装されている、2を採用したいところ。
んで、どこら辺から穴が開くかを考えると、
A.cookie盗まれる
B.通信路盗まれる
C.サーバデータ盗まれる
D.ブルートフォースアタック
A.は2.特有の問題。
B. C.はどちらでも発生するしcgiで考えることはpermission位。無視。
D.はどちらでも発生するが、フォームでのパスワード入力にブルートフォースをかけるのは難しい。認証失敗ページに飛ばすようにすれば、まず問題ないだろう。となるとこれも2.だけの問題でcookieを偽装生成してブルートフォースをかけるという手段が残る。これは比較的やりやすい。
各論。
A.cookie盗難はもうどうしようもない。これがイヤなら、別の通信方法を考えるか2.の実装を止める必要がある。ユーザが気をつけること、で終了するしかないだろう。
cookieを偽装する場合のD.ブルートフォースに関して言うと、名前と値をペアで生成する必要があるためcookie名が"password"など一般的なものでない限り、そう脆くもない。cookie名は多少ひねっておこう。
passwordを平文でcookieに保存するのがイヤであるなら、MD5値(ハッシュ関数)などを設定するようにする。短いパスワードの危険性が多少軽減されるほか、pathの設定ミスによる同ドメイン他者へのパスワード漏洩の危険が下がる。
最初セッションごとにidを生成し、セッションidをcookieとサーバ上に記憶しておいて照合、ということを考えたが、複数管理者の実装が難しい(サーバのファイルにゴミが残りやすい or 管理者1人のみ)となる。passwordハッシュ値が多分妥当な線だろう。
……さて、怪しい知識でここまで書いてしまったが危なかったら指摘して欲しい。
それにしても私が使っているCGI(KShiki,Nicky)は皆、パスワードを平文のままクッキーにつっこんでいる。……こんなんでいいんだろうか?
P.S.友人からRemotehost情報加えてハッシュにかけてはどうかという提案がありました。この場合、cookieを抜かれても、抜いたユーザのリモートホストまで偽装をしなければいけないので、クラックのハードルはぐんと上がりますのでこちらの方が妥当です。ただ、定期的にproxyを切り替えるユーザやプロバイダ2契約でセッションを切り替えるユーザには使えなくなりますか。最近だと、後者が結構居るという話ですが、実態は不明(Flet'sには2セッションはれるのに、プロバイダが1セッション契約な為)
<参考URL>
http://www.yanagisawa.ws/WBL/ASP/session.asp
http://akademeia.info/main/security_lecture.htm
http://www.futomi.com/lecture/cookie/specification.html