注意: この文書は私の拙い知識と経験を元に書かれているので、 間違いが含まれている可能性があります。
ウェブサイトでHTTPクッキーや認証機能を利用したセッション管理には CSS に類似した問題点があり、 外部から任意の操作をさせる攻撃が可能になります。 (ただし、セッションを乗っ取られることはありません。)
HTTP は根本的に "状態" を持たないプロトコルです。 このため、多くのサイトでは HTTPクッキーまたはHTTPの認証機能を利用して状態を保持し、 仮想的に "セッション" を作り出しています。
クッキーを利用する場合には、 ユーザ名とパスワードの組み合わせまたはユニークなIDを記憶させます。 一度 "認証" が行われた後には、 ユーザがそれを意識すること無くそのデータが送信されます。
また、HTTP認証を利用して一度IDとパスワードを入力した場合、 多くのクライアントの実装は同一の "realm" に対して自動的にIDとパスワードを送信します。 したがってクッキーの場合と同様、 "認証" 後はユーザがそれを意識すること無く自動的に送信されます
多くのクライアントの実装では、 複数開いたどのウィンドウからアクセスした場合でも同様に "認証" 情報がサーバに対して送信されます。 このため、悪意あるサイトにアクセスすることによって、 そのIDがもつ権限で様々な操作が行われる可能性があります。 具体的には、 掲示板へのポストやショッピングサイトにおける購入決定など、 表示以外にも影響を及ぼす操作で問題が生じます。
HTTP認証機能によるアクセス制限またはクッキーによるセッション管理が行われ、 それ以外の "認証" は全く必要とされない掲示板CGIプログラムを想定します。 また、掲示板の記事を管理者権限で削除するには、 管理者権限を持つIDで "認証" を済ませた状態で
に対して以下のqueryを送信するものとします。
GET メソッドによる query の送信を受け付ける場合は "認証" を済ませた状態にある管理者に対して、 以下のURLにアクセスさせるだけで 1234 の記事を削除することが可能です:
これは、クライアントには既に "認証" 済みの情報が記憶されてあり、 そのアクセスのときには自動的に送信するためです。(図1)
(user)
+----------------+
| +-window 0---+ | +------------+
| | | | request / auth info | |
| | -+-+------------------------------->| target site|
| | | | +--------------------------->| |
| +------------+ | | request / auth info +------------+
| | |
| +-window 1---+ | |
| | | | |
| | -+-+---+
| | | |
| +------------+ |
+----------------+
図1
単に上記URLにアクセスさせず、 http://evil-site/safe.html のように一見安全に見えるページからリダイレクトさせると ユーザはそれを意識することはできません。(図2)
(user)
+----------------+
| +-window 0---+ | +------------+
| | | | request / auth info | |
| | -+-+------------------------------->| target site|
| | | | +-->| |
| +------------+ | | +------------+
| | request / auth info | (redirect)
| +-window 1---+ | | +------------+
| | | | +---| |
| | -+-+------------------------------->| evil site |
| | | | | |
| +------------+ | +------------+
+----------------+
図2
また、
<img src="http://target-site/bbs.cgi?action=delete&num=1234" />
と記述されたHTML文書にアクセスさせることで同様の効果を得ることが出来ます。
"認証" を済ませた状態にある管理者に対して 以下のような偽のフォームを使用して送信させることで、 1234 の記事を削除させることができます。 このとき、ユーザ側からはあたかも Yahoo! の検索をするように見えています。 (図3)
<form action="http://target-site/bbs.cgi" method="POST"> <input type="hidden" name="action" value="delete" /> <input type="hidden" name="num" value="1234" /> Yahoo! 検索: <input type="text" name="dummy" /> </form>
(user)
+----------------+
| +-window 0---+ | +------------+
| | | | request / auth info | |
| | -+-+------------------------------->| target site|
| | | | +------------(2)------------->| |
| +------------+ | | request / auth info +------------+
| | | (実際のアクセス)
| +-window 1---+ | | +------------+
| | -+-+--+ | |
| | -+-+---------------(1)------------->| evil site |
| | -+-+- + | (偽form) |
| +------------+ | +------------+
+----------------+ |
+------------+
| | |
- - - - - - (2) - - - - - - >| Yahoo! |
ユーザの認識 | |
+------------+
図3
JavaScript など、 クライアントサイドで動作するスクリプトを利用して自動的に POST させることが可能です。 たとえば Internet Explorer の場合、 以下のようなフォームを用意することで自動的に POST させることが可能です。
<body onload="document.dummy.submit()"> <form action="http://target-site/bbs.cgi" method="POST" name="dummy" style="visibility: hidden"> <input type="hidden" name="action" value="delete" /> <input type="hidden" name="num" value="1234" /> </form> </body>
表示以外にも影響を与えるような機能を利用する場合には、 その度ごとに改めてパスワードを入力させるインターフェイスを採用 することでこのような攻撃を防止することができます。 たとえば、Yahoo! オークションでは、 入札時に金額に加えてパスワードを入力する方法が採用されています。
このほか、Referer: の情報を利用して、 正規のサイトから呼び出されたかどうかを判定する方法があります。 Referer: の情報は偽ることが可能なので クライアント側に悪意がある場合には利用することが出来ませんが、 このような場合には有用です。