Webアプリケーションのぜい弱性がなかなかなくならない。メディアなどでも盛んに取り上げられているにもかかわらず,である。特に,セッション管理がからむアプリケーションのぜい弱性には,気付かないことが多い。具体的には「クロスサイト・リクエスト・フォージェリ」(CSRF),「セッション・フィクセーション」などである。これらはクロスサイト・スクリプティング,SQLインジェクションといった比較的メジャーなぜい弱性に比べて認知度が低く,対策も進んでいない。

 原因の一つは,アプリケーションの開発者が原因を正しく理解していないこと。CSRFやセッション・フィクセーションについて言えば,セッション管理に使うクッキー(cookie)の動作を理解していないと対策が難しい。ところが最近の開発環境では,セッション管理の仕組みが隠ぺいされているため,必ずしもこの知識は要求されない。こうした開発者は容易にはぜい弱性に気付けない。

 最近,セッション管理に関連するぜい弱性が顕在化するようになってきた。例えば2007年秋にはGmailや無線LAN製品に付属する管理アプリケーションなどに相次いでCSRFのぜい弱性が報告された。2008年1月にはヤマハのブロードバンド・ルーターにも同様のぜい弱性が発覚した。潜在的にこれらのぜい弱性を抱えているアプリケーションは少なくない。今後も同様の報告が増加することが予想される。

 開発者が対策を講じるには,セッション管理の原理を理解したうえでアプリケーションを見直す必要がある。本稿では,セッション管理を悪用する攻撃と対策,および更なる問題の例としてセッション変数使用時の注意点を,クッキーの仕組みを基に解説する。

 携帯電話向けアプリケーションを除き,Webアプリケーションにおけるセッション管理ではクッキーを使うことが多い。そこでまず,クッキーの仕組みを解説しよう。

 Webアプリケーションは本来,アプリケーションの「状態」を持たない。プロトコルとしてHTTPを使うためだ。あるユーザーから送られてきた前回のリクエストと,今回のリクエストを関連付けることはできない。ただ,これではユーザー認証を必要とするようなアプリケーションを実現できない。そこでWebアプリケーションの黎明期には,ユーザーはURLに識別情報を含める方法でセッション管理を実現していた。

 ところがこの方法は,実装が複雑な上,セキュリティ上の問題が発生しやすいなどの欠点を抱えていた。そこで考案されたのがクッキーである。起源は米ネットスケープ・コミュニケーションズが提案した仕様である。その後,RFC 2109,RFC 2965と規格化が進められたものの,現状では主要なブラウザはネットスケープ仕様を採用している。以下ではNetscape仕様に基づいて解説を進める。

 クッキーによるセッション管理は,以下の手順で実現される(図1)。

図1●クッキーの役割
図1●クッキーの役割

1. Webアプリケーションが,Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure (NAME=VALUEのみ必須)という形式のHTTPヘッダーを含めて,レスポンスを返す。

2. ブラウザが,この値をURLにひも付けて保持する。

3. 次にアクセスする場合,ブラウザは保持しているクッキーを検索し,送信先のURLにひ も付けられたすべてのクッキーをCookie: NAME1=OPAQUE_STRING1; NAME2=OPAQUE_STRING2 ...

という形式のHTTPヘッダーに含めて,リクエストを送信する。

 では,このクッキーが盗まれたとしたら,どんな問題が発生するだろうか。

 攻撃者は自分が送信するリクエストに盗んだクッキーを含めることで,本来のクッキーの持ち主になりすますことができる(図2)。サーバーはクッキーの内容を見てクライアントを判別するだけで,送信されてきたクッキーが盗まれたものであるか否かは判断できないからだ。

図2●クッキーを盗まれると不正利用を許してしまう
図2●クッキーを盗まれると不正利用を許してしまう

 クッキーの盗難に関する問題は軽視されがちである。クライアント・パソコンに記録されたクッキーを盗み出すのは容易ではないというのがその理由だ。それでも,なりすましが成功すれば個人情報漏えいなど重大な被害が発生してしまうことは,直感的に理解できるだろう。

 では,どのようにクッキーを保護したらいいか。対策は,クッキーの仕様で定義されている属性のパラメータを注意深く設定することである。クッキーの属性としては,secure属性,expires属性などが挙げられる。これらは正しく設定されていないことが多い。

[secure属性]:HTTPSの通信時のみクッキーを送信する

[expires属性]:クッキーの有効期限を指定する

 secure属性が指定されていないと,暗号化されていない通信経路上にクッキーが送信されてしまい,盗聴される危険がある。最近の開発環境では,アプリケーション・サーバーや,フレームワークがsecure属性の設定を自動的に設定することが多いため気付きにくいかもしれない。マニュアルを確認し,正しく設定する必要がある。

 expires属性は,被害が発生してしまう可能性と関連する。この指定がある場合,指定された日時までクッキーが送信される。つまり,クッキーは指定された日時までファイル上に保存され,ブラウザ再起動後もその値が読み込まれ使用される。指定がない場合,有効期限はブラウザが終了するまでとなる。

 この属性が指定されていなければ,ブラウザを起動していないユーザーが被害に遭うことはない。しかし,この属性が指定されていると,ブラウザ起動時にクッキーが自動的に読み込まれ送信されるため,ブラウザを起動していないユーザーも被害に遭う対象となる。この属性は,オートログイン機能を実現するために設定されることが多いが,このようなリスクが発生することは認識しておかなければならない。

 ほかの属性についても説明しておこう。domain属性とpath属性だ。これらは,ブラウザがクッキーを自動送信する仕組みに関連がある。

ブラウザからクッキーが送信される条件

 「次の要求があった場合,ブラウザは保持しているクッキーを検索し,送信先のURLにひも付けられたすべてのクッキーをHTTPヘッダーに含めてリクエストを送信する」ことは前述した。

 ひも付けがないと,あるサイトの状態維持に使用しているクッキーが別のサイトにも送信されてしまうため,送信には条件が定められている。その条件は,Set-Cookieで指定される属性のうち,path=PATH; domain=DOMAIN_NAME の部分により決定される。それぞれの属性の意味は以下の通りだ。

[domain属性]

 ブラウザがクッキーを送信するサーバーのドメイン名。ブラウザがアクセスするURL内のドメイン名がこれに後方一致(一部制限がある)する場合のみクッキーを送信する。後方一致しない場合はブラウザにセットしない。省略した場合は,アクセスしたURLに含まれるホスト名が使用される。

[path属性]

 ブラウザがクッキーを送信するサーバーのパス。ブラウザがアクセスするURL内のパスがこれに前方一致する場合のみクッキーを送信する。前方一致しない場合はブラウザにセットしない。省略した場合は,アクセスしたURLに含まれるパスが使用される。

 こう書くと若干複雑に感じられるかもしれない。簡単にいうと,アクセスしようとしているURLがhttp://example.co.jp/pathならば,そのURLから発行されたクッキーがブラウザにより自動送信されるということである。

 クッキーが送信される条件は,普段はあまり気にとめられない。ただ,Webアプリケーションのセキュリティ上の問題の多くは,クッキーの仕組みゆえに発生する。ぜい弱性を理解するために必要な知識である。次回からは,クッキーの仕組みを使ったセッション管理に潜むぜい弱性と,それを悪用した攻撃手法について解説する。


安西 真人
ユービーセキュア 技術本部 テクニカルサービス部 セキュアナレッジコンサルタント 兼 Webアプリケーション検査ツールVEX開発エンジニア
プログラマを経て2年前からセキュリティ業務に従事している。