事件簿3 価格を簡単に詐称できた

図3●商品の単価をCookieに格納していた
図4●ファイアウォールや侵入検知システムでは防げない
ネットワーク,OSや基本ソフトウエアのレベルをいくら固めても,その上で動作するWebアプリケーションにぜい弱性があれば,重要データが漏えい/改ざんされてしまう
図5●SSLを使っていてもCookieの改ざんは防止できない
図6●Webブラウザから送信するHTTPリクエストの中身
図7●Webサーバーが返すHTTPレスポンスの中身

 最後は,通信販売事業者向けにショッピング・サイトの機能をサービスとして提供しているASP事業者C社の例である。C社のサービスは,多くのショッピング・サイトにあるように,購入したい品物をWeb上の架空の買い物カゴ(ショッピング・バスケット)に入れ,決済ボタンをクリックするとクレジット決済の画面を表示する設計になっていた。このショッピング・バスケットの機能は,Cookieを利用して実現されていた。商品の品番,名称,単価,数量などをすべてCookieに格納していたのだ(図3[拡大表示])。

 しかし,事件簿1で説明したように,Cookieの中身は容易に改ざんできる。この場合,Cookieに単価を含めていることが問題であり,容易に価格を詐称できる状態になっていた。例えば,図3上にある「248000」を「1」に改ざんすると,マッサージ機を1円で購入できてしまう。実際に価格を詐称されることはなかったが,セキュリティ対策が不十分なサービスを顧客企業に提供していたことになる。

 この問題はセキュリティ研究者からのメールにより指摘され,C社は直ちに対策をとった。具体的には,ショッピング・バスケットの実現方法を見直し,Cookieには品番と数量のみを保存するように変更した。価格詐称事件に至らなかったとはいえ,顧客企業に与えた不安は大きく,経営的に大きなダメージとなった。

ファイアウォールでは防げない

 「なりすまし」「個人情報漏洩」「価格詐称」――いずれもセキュリティ上の事件としては非常にインパクトの大きなものだ。では,これらの事件はファイアウォールやIDS(侵入検知システム)*8といった従来のセキュリティ対策で防げるのだろうか。答えはノーだ。

 なぜならファイアウォールやIDSでは,OSやWebサーバーといった基本ソフトウエアに対する攻撃や,公開していないサービスへのアクセスを遮断することしかできないからだ。これに対して上記で紹介した例は,いずれもHTTPという正規のプロトコルによるリクエストで実現可能であり,ファイアウォールやIDSでは検知/遮断されない(図4[拡大表示])。これを検知するには,HTTPでやり取りするデータが,前後の関係から見て妥当な内容になっているかどうかを調べなければならない。これはかなりインテリジェントな判断を要することになる。

 例えばCookieが改ざんされているかを確認するためには,サーバー側で設定されたCookieの値をセッションごとに記憶しておき,クライアント(Webブラウザ)から要求があるたびにCookieの値を比較する必要がある。これはHTTPでやり取りする内容を詳しく調べなければできないため,従来のファイアウォールのように,単純に通信ヘッダーやポート番号などを確認するアプローチでは実現できない*9

 また,SSL(Secure Sockets Layer)で通信を暗号化していたとしても,上記の事件は防げないので注意する必要がある。サイト全体をSSLで保護すればCookieの改ざんを防止できそうだが,よく考えてみてもらいたい。SSLはクライアントとサーバーの間の通信路を暗号化し,改ざんを防止するだけである。つまり,通信路での改ざんを防ぐことは可能だが,クライアント側での改ざんまでは防止できない(図5[拡大表示])。

 このように,既に多くの企業で導入されているファイアウォールやSSLといったセキュリティ対策では,Webアプリケーションのぜい弱性を防ぐことはできない。

ぜい弱性が発生する仕組みを理解する

 では,なぜWebアプリケーションにぜい弱性が生まれてしまうのだろうか。これを理解するには,Webアプリケーションの基本原理を把握する必要がある。具体的には,HTTPやHTML,JavaScriptなどの技術に基づいたシンプルな原理である。

 Webアプリケーションは多数のHTMLページで構成されており,ページとページの間は,リンクまたはHTMLフォームのSubmitボタンでつながれている。アプリケーションのロジックは,ページを遷移するタイミングで実行される。a.htmlというページからb.cgiというページに遷移する場合を例に説明しよう。

 a.htmlに表示されたSubmitボタンをクリックすると,クライアント(Webブラウザ)からWebサーバーにHTTPリクエストが送信される(図6[拡大表示])。HTTPリクエストには,1行目のGETコマンドの中にb.cgiのURLならびにURLのパラメータ(ITEM=1)が指定されているほか,HTTPヘッダーとして様々なパラメータがWebブラウザにより付与されている。通常,CGIプログラムなどで利用されるものとしては,Cookie,User-Agent,Refererなどがある。User-AgentはWebブラウザの種類,Refererはリンク元のURLを意味している。なお,GETコマンドの代わりにPOSTコマンドを利用することもある。その場合,HTMLフォームに入力したパラメータは,URLの後ではなくHTTPヘッダーの後に続いて送信されることになる*10

 Webサーバー(ApacheやIISなど)はHTTPリクエストを受け取ると,必要に応じてCGIプログラムなど(ASP*11やJavaサーブレットを含む)を起動し,その実行結果をHTTPレスポンスとしてWebブラウザに返す(図7[拡大表示])。Webブラウザはこのレスポンスを受け取り,その中に含まれているHTMLを表示したりJavaScriptを実行したりすることになる。

 ここで問題になるのは,「CGIプログラムなどが受け取るパラメータ類は基本的にクライアント(Webブラウザ)から送信されるHTTPリクエストの中にあるデータであり,これらはすべて改ざん可能である」という点だ。中でも,Cookie,hiddenフィールド*12,Referer,User-AgentなどWebブラウザが自動的に付与するHTTPヘッダーの改ざんについては,盲点となりやすいだけに厳重な注意が必要である。

 簡単に言ってしまえば,Webアプリケーションのぜい弱性のかなりの部分は「HTTPヘッダーが改ざん可能である」という点に起因している。この性質はHTTPの欠点とも言える。しかし,これだけWebが普及した理由の一つが,HTTPの単純明快さにあるとも言えるわけで,欠点を嘆いていても仕方がない。むしろ,HTTPの性質を正しく理解し,ぜい弱性の入り込まないアプリケーションを開発することに注力すべきだろう。