分12前回は,Webアプリケーションにおける受動的攻撃の代表例として,以下の4つを挙げました。クロスサイトスクリプティング(XSS)クロスサイトリクエストフォージェリ(CSRF)オープンリダイレクトクリックジャッキング今回は,これらのうち,XSSについてより掘り下げて解説していきます。XSSはどのようにして引き起こされるのかXSSとは,動的にHTMLを生成するWebアプリケーションにおいて,データをエスケープせずに出力しているために,生成されるHTMLに攻撃者の作成したHTML断片やJavaScriptコードが埋め込まれてしまう脆弱性です。検索画面にてユーザーが「HTML5」という文字列を入力すると,http://example.jp/search?q=HTML5というURLで検索結果が表示されるWebアプリケーションがあったとしましょう。検索結果の画面では,ユーザーが入力した文字を強調表示するために,以下のように<span>タグによって囲まれているとします。class="keyword">HTML5</span>」を検索しました。20件の文書が見つかりました。class="keyword"><script>alert(1)</script></span>」を検索しました。20件の文書が見つかりました。ようになり,本来文字列として表示されるべき検索語句が<script>要素として有効になってしまい,ブラウザ上ではJavaScriptが動作してしまいます。誘導することで,ユーザーのブラウザ上でJavaScriptを実行させることができます。Enumeration:共通脆弱性タイプ)ではこれらを区別せず,どちらも「クロスサイトスクリプティング」と呼んでおり(http://jvndb.jvn.jp/ja/cwe/CWE-79.html⁠)⁠,両者を区別する必要はないでしょう。上でユーザーが行えるすべての操作を攻撃者はJavaScriptによってユーザーのブラウザ上で行うことができるということになります。ユーザーのブラウザ上に偽のテキストや偽のログインフォームを表示し,そこへ入力された情報を搾取することもできますし,httponly属性のついていないCookieであればJavaSciriptから盗み見ることもできます。画面上に表示されている機密情報やプライベートな情報をJavaScriptを通じて読み取ることもできます。攻撃者がXSSを使って以下のようなJavaScriptコードをHTML内に挿入し,ユーザーのブラウザ上でそのJavaScriptが実行されたとします。ユーザーの使用しているCookie情報が送信されることになってしまいます。XSSによって発生する脅威は,一般的には以下のようなものになります。偽情報の表示(JavaScriptによって,本来はWebサイト上に表示されていない偽の情報を自由にHTML上に表示できる)フィッシング(JavaScriptによって,偽のログインフォームやお問い合わせフォーム,住所登録フォームなどを表示することで,ユーザーのプライベートな情報を登録させ,それを搾取できる)強制的なWebアプリケーションの操作(JavaScriptによって,強制的に画面上のページ遷移や操作を攻撃者が行える)セッション情報の漏洩(Cookieにhttponly属性がつけられていない場合,JavaScriptからdocument.cookieを読み取ることによって,攻撃者はCookieに含まれるセッション情報を盗み見ることができる。httponly属性がついている場合であっても,ブラウザによってはJavaScriptからdocument.cookieへの書き込みはできるので,攻撃者があらかじめ用意したセッションを強制的に利用させることも可能)機密情報の漏洩(JavaScriptからHTMLを読み取れるため,攻撃者はHTML内に含まれる氏名や住所などのユーザーの機密情報を盗み見ることができる)これらの脅威はあくまでも代表的なものであり,実際にはXSSの存在するWebアプリケーションの性質によって変わってきます。ログイン機構を持たないWebサイト内の検索画面におけるXSSであれば,セッション情報の漏洩については大きな脅威とはならないこともあります。逆に,Webメールのように利用者個人と強く紐づく大量の機密情報を取り扱うWebアプリケーションでは,ひとたびXSSが発生すると,ユーザーにとっては大きな脅威となりえます。実際に,2005年にはSNSサイトであるMySpace内でXSSを利用して拡散するワーム「Samy」が,2006年にはWebメールであるYahoo!メールにおいても同様にXSSを利用して自身を拡散させるワーム「Yamanner」が発生しています。XSSの原因と対策XSSが発生する代表的な原因としては,以下のようなものが挙げられます。テキストノードでのエスケープ漏れ属性値への出力でのエスケープ漏れ属性値への出力を引用符で囲っていないリンク先URLにhttpやhttps以外のスキームが入力可能これら以外にもさまざまな原因でXSSは発生しますが,それらについては直面する機会も少ないため割愛します。XSS)については,今後の回で詳細に解説します。今回は,従来からのXSSの代表的な原因について,より深く見ていきましょう。XSSのうち非常に多くが,HTML上は本来テキストノードあるいは属性値として出力すべきデータを適切にエスケープせずにそのまま出力していることで引き起こされています。先の例では,以下のように本来は<span>要素内にテキストノードとして出力すべき箇所にて「<」「⁠>」といったメタキャラクタをそのまま出力しているためにXSSが発生しています。class="keyword"><script>alert(1)</script></span>」を検索しました。20件の文書が見つかりました。テキストノードへの出力の際のエスケープ漏れだけでなく,「⁠<input>要素などの属性値へ文字列を出力する際に属性値が引用符で囲まれていない」「⁠属性値がエスケープされていない」といった原因でXSSが発生する例も非常によくあります。ようなURLの指定において,<input>要素のvalue属性に指定された値を埋め込んで出力するWebアプリケーションがあったとします。onmouseover=alert(1)」のような文字列を指定すると,以下のようなHTMLが生成され,ユーザーがこの<input>要素の上でマウスを動かすとJavaScriptが実行されてしまいます(※1⁠)⁠。onmouseover=alert(1)>属性値を引用符で囲っている場合であっても,属性値がエスケープされていない場合にはXSSが発生します。攻撃者が「"onmouseover=alert(1)//」のような文字列を指定すると,以下のようなHTMLが生成され,onmouseover以降がvalue属性の値ではなくイベントハンドラとして有効になってしまうためにXSSが発生してしまいます。value=""onmouseover=alert(1)//">従来から存在するXSSの非常に多くが,この「テキストノードでのエスケープ漏れ」「⁠属性値への出力でのエスケープ漏れ」「⁠属性値への出力を引用符で囲っていない」のいずれかを原因としています。以下の2つの対策を徹底して行うことで,XSSの発生を防ぐことができます。(1)文字列を出力する際には,テキストノードあるいは属性値としてのみ解釈されるように適切にエスケープを施す(2)属性値を出力する際には,引用符で囲む※1)ユーザーの操作を介在させずにJavaScriptを動作させる方法も存在します。機会があれば,回を改めて説明します。XSS著者プロフィールはせがわようすけ株式会社セキュアスカイ・テクノロジー常勤技術顧問。FirefoxをはじめWebアプリケーションに関する多数の脆弱性を発見。