最近Webアプリケーションに存在するセキュリティホールが注目を浴びている。その中でも「クロスサイトスクリプティング」と呼ばれる脆弱性が有名であるが、クロスサイトスクリプティング脆弱性について正確に理解している人が依然として少ないと感じる。
本稿では、クロスサイトスクリプティングとはどのような脆弱性であるのか、この脆弱性を持ったサイトが攻撃されるとどのような被害が起き得るのか、なぜそのようなセキュリティホールが作り込まれてしまうのか、どのように対策をすればよいのかを解説していく。
※以下本文中では、クロスサイトスクリプティング脆弱性のことを「XSS」と表記する。「Cross Site Scripting」の略であるから「CSS」と表記している記事もあるが、「Cascading Style Sheets」の略も「CSS」となり紛らわしいため、「XSS」と表記する場合が多くなってきている。本稿でも「XSS」と表記することにする。
先日、OpenSSL、Apache、Squidのような有名なアプリケーションでセキュリティホールが見つかった。これらのアプリケーションを作成したプログラマたちはセキュリティについて気を使いながらプログラミングを行っていたことであろう。しかし、ちょっとしたミスや見落としによりセキュリティホールを作り込んでしまった。これに対して個別のWebサイト用に開発されたWebアプリケーションはどうだろうか。おそらく、セキュリティについての知識がないプログラマが開発している、あるいは知識もあり意識して開発しようとしているが納期や予算の関係でセキュリティ対策を後回しにして開発している場合がほとんどではないだろうか。そのような状態で、まともにセキュリティ対策の施されたアプリケーションが出来上がってくることはまれだろう。
これまで、Webサーバのセキュリティ対策というと一般に次のようなものが知られている。
これらの対策方法は防御できる範囲に制限があり、複数の対策方法を組み合わせて使わないとサイトを守るには不十分となる。表1は、それぞれの対策方法がカバーするプロトコル範囲をまとめてある。
ファイアウォール | IDS | ウイルスチェック | 改ざん検知 | |
---|---|---|---|---|
HTML | × | △ | × | × |
HTTP(s) | × | ○ | × | × |
TCP/IP | ○ | ○ | × | × |
表1 各対策方法がカバーするプロトコル範囲 |
これに対して、それぞれのプロトコルがどのプログラムによって処理されるのかを追加したものが次の表である。
ファイアウォール | IDS | ウイルスチェック | 改ざん検知 | プログラム | |
---|---|---|---|---|---|
HTML | × | △ | × | × | 個別Webアプリケーション |
HTTP(s) | × | ○ | × | × | HTTPD(Apache、IISなど) |
TCP/IP | ○ | ○ | × | × | OS |
表2 各対策方法がカバーするプロトコル範囲と処理するプログラム |
この表から分かるように、個別Webアプリケーションが処理する部分については、ほとんど防御されていない。さらにこの個別Webアプリケーションとは先に述べたとおりセキュリティ対策がまともにできていないアプリケーションである。IDSは△としたが、わずかな一部の攻撃に対してのみ有効なだけである。IDSは基本的に、あらかじめ登録されているパターンの攻撃がされたときにそれを検知する。しかし、HTMLなどを処理するアプリケーションはWebサイト固有のものであるので、それに対する攻撃も千差万別である。そのためIDSはWebアプリケーションに対する攻撃の大部分は検知することさえできないのが現状である。
上記の理由により、多くの脆弱なWebアプリケーションが無防備なまま、インターネットからの攻撃の脅威にさらされているのである。
Webアプリケーションに対する代表的な攻撃手法として、次のような攻撃がある。
これらの攻撃は従来のHTTPDやOSに対する攻撃と異なり、
という特徴を持っている。
これらのWebアプリケーションに対する攻撃手法のうち、今回はXSSを取り上げている。
前置きが長くなってしまったが、XSSの仕組みについて説明する。XSSを利用して攻撃が行われるのは、ユーザーの入力に対して動的にHTMLページを生成するアプリケーションが対象になる。静的なページ、つまり通常のHTMLページではこの問題は起こらない。
例として次のようなアプリケーションを考えてみる。
図1のようなテキスト入力欄があり、そこに名前を入力して送信ボタンをクリックすると、ユーザーが入力した名前がページの一部となって表示されるアプリケーションがあるとする(図2)。非常に単純な例ではあるが、ユーザーが入力した文字列を使って動的にHTMLページを生成し出力しているためXSSが入り込む可能性のあるアプリケーションである。
ブラウザの機能でこのページのソースを見ることができる。出力されているHTMLは、次のようになっている。
<html> <body> ようこそkokubuさん </body> </html>
HTMLとしては間違った文法であるが XSSの問題とは関係ない。
さて、ここで名前の入力欄にHTMLタグを使用した「<s>kokubu</s>」という“名前”を入力してみる。この場合はどうなるだろうか。XSS対策が不十分なWebアプリケーションのほとんどがkokubuの部分に取消線が引かれた“名前”が表示される(図3)。
このとき、出力されているHTMLは、次のようになっている。
<html> <body> ようこそ<s>kokubu</s>さん </body> </html>
本来、「<s>kokubu</s>」という文字列をブラウザ上に表示したい場合は、「<s>kokubu</s>」としなければならないのだが、その処理が抜けてしまっているのだろう。
さらに、名前入力欄にscriptタグを使用した「<script>alert("XSS");</script>」という“名前”を入力してみる。すると、XSSと書かれたダイアログボックスが表示される。
出力されているHTMLは、次のようになっている。
<html> <body> ようこそ<script>alert("XSS");</script>さん </body> </html>
HTML文中に「<script>alert("XSS");</script>」というダイアログボックスを表示するためのスクリプトが入っている。ブラウザはこれをスクリプトと解釈してダイアログボックスを表示している。ここではダイアログボックスを表示するだけの無害なスクリプトを実行させたが、ほかの任意のスクリプトを実行することもできるだろう。これがクロスサイト“スクリプティング”と呼ばれる理由の1つである。
これだけだと自分が入力したスクリプトを自分が実行するだけであるので何の問題もないだろう。しかし他人が作成したスクリプトを実行させられるとしたら脅威となることが分かっていただけるだろう。実際このように簡単に実現することができる。
このアプリケーションを例に取って考えてみる。先ほどのダイアログボックスが表示されていた画面のURL欄を見ていただきたい。
URLの部分に「name=%3Cscript%3Ealert%28%22XSS%22%29%3B%3C%2Fscript%3E」と表示されているのが分かる。これはURLエンコードという方式でエンコードされた文字列で、デコードしてみると「name=<script>alert("XSS");</script>」となる。このアプリケーションでは、名前入力欄に入力した名前がURLの後ろに追加されてアプリケーションに渡され、アプリケーションはこの文字列を読み取り、出力画面の一部としてブラウザに表示させる、という仕組みを取っている。このURLのパラメータ部分を「name=%3Cscript%3Ealert%28%22Cross Site Scripting%22%29%3B%3C%2Fscript%3E」と書き換えたURLにアクセスすると、図6のように「Cross Site Scripting」と書かれたダイアログボックスが現れる。
これを利用して攻撃者は、このアプリケーションがあるサイトとは別のサイトに次のようなページを用意する。
<html> <body bgcolor="black" link="white"> <a href='https://脆弱サイト/hello.cgi?name=<script>alert("XSS");</script>'> ここをクリック</a> </body> </html>
攻撃者はユーザーに対して、このページにアクセスするように仕向ける。攻撃者のサイトにアクセスしたユーザーがこのリンクをクリックすると、
https://脆弱サイト/hello.cgi?name=<script>alert("XSS");</script>
というURLにアクセスすることになり、先ほどのスクリプトが実行される。攻撃者のサイトから攻撃対象のサイトというようにサイトをまたがる(クロスする)ことから、“クロスサイト”スクリプティングと呼ばれる。
では、これまで説明したXSSの流れをまとめてみよう。
これが最も基本的な場合のステップであるが、ほかにもさまざまなバリエーションがある。このステップで一番ネックになりそうなのが1と3で、ユーザーが何らかの操作をしなければならないようになっている。しかし、攻撃者は巧妙な仕掛けで無意識のうちにユーザーが1と3の動作をしてしまうような仕組みを作るだろう。
例えば、ユーザーがリンクをクリックするのを待つのではなく、自動的に次のページへ飛ぶような方法がある。「このページは移動しました。○○秒後に自動的に移動します」といったページを見掛けることがよくあるが、原理はそれと同じである。このようなページを作成しておけば、3のステップをユーザーが無意識のうちに行わせてしまうことができる。
また、メールで直接URLを送りつけてしまったり、大勢の人がよく見る掲示板に先ほどの仕掛けを仕込んでおくなどの方法で、簡単に1も実行させられる。
実は今回説明に用いた例ではHTTPSを使っていた。HTTPSでは途中経路が暗号化されているため、暗号化されているデータが流れているネットワークに設置してあるIDSでは、どんなことをしても検知できないだろう。さらにSSLの証明書により、スクリプトが正しいサイトから送られてきていることが保証されるという、皮肉な結果となっている。
今回は、パラメータ値がURLに含まれるGETメソッドでのアクセスを例に挙げたが、パラメータ値がURLに含まれないPOSTメソッドでのアクセスでも同様のことが起こる。POSTメソッドを使うだけでは何の対策にもならないことに注意していただきたい。
次回は、実際にどのような被害が起き得るか、実際のプログラミング工程でどのようなミスをしていて、さらにどのように対策をすればよいかについて説明する。
国分 裕(こくぶ ゆたか)
三井物産株式会社GTIプロジェクトセンタ勤務。セキュリティコンサルタントとして、不正アクセス監視やセキュリティ検査 などに従事している。金融機関、官公庁、大手製造業などへのセキュリティシ ステムの導入、セキュリティ検査などの実績を持つ。
三井物産株式会社GTIプロジェクトセンタ(現:三井物産セキュアディレクション株式会社)
主に、不正アクセス監視サービス、セキュリティ検査、セキュリティポリシー策定支援などのサービス提供している。また、セキュリティに関する教育サービスも実施中。
Copyright © ITmedia, Inc. All Rights Reserved.