BLOG
ブログ
  • TOP
  • BLOG
  • クロスサイトスクリプティングとは

クロスサイトスクリプティングとは

クロスサイトスクリプティングとは

CONTENT

■はじめに
クロスサイトスクリプティング(以下、XSS)とは、おおまかに言えば、攻撃者がWebアプリケーションの入力欄やURLパラメータなどを悪用し、本来は表示されるだけのコンテンツに任意のスクリプトを混入・実行させる脆弱性、またはその脆弱性を利用した攻撃のことです。

場合によっては、ページの表示内容をまったく別物に改変したり、利用者の操作を偽装したりすることも可能になります。では、なぜこの攻撃は「クロスサイト」、つまり「サイト横断型」と呼ばれているのでしょうか。

■ある架空の事例
脆弱性がある場合
とあるECサイト「サイトA」に、商品の検索機能があるとします。たとえば、次のようなリクエストが行われたとします。

https://ec-site-A.com/search/?keyword=%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3
このとき、検索結果とともに次のHTMLが出力されるものとします。

<input type="text" value="パソコン">
ここまでは、ごく普通の検索画面です。

しかし、入力値を適切にエスケープせず、そのままHTMLに埋め込んでいる場合、次のようなURLを読み込ませることで問題が起こります。

https://ec-site-A.com/search/?keyword=%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%22%3E%3Cscript%3Ealert%28%22%E5%8D%B1%E9%99%BA%E3%81%A7%E3%81%99%EF%BC%81%22%29%3B%3C%2Fscript%3E%3Cbr+style%3D%22%0D%0A
このリクエストによって、次のようなHTMLが出力されてしまう可能性があります。

<input type="text" value="パソコン"><script>alert("危険です!")</script><br style="">
本来は検索キーワードとして扱われるべき文字列が、HTMLの構造を壊し、scriptタグとして解釈されてしまいました。

この例では警告ダイアログを表示しているだけですが、実際には、スクリプトの内容によっては利用者の情報を外部サイトへ送信したり、画面上の表示を改ざんしたりすることも考えられます。

■攻撃の全体像
この脆弱性を悪用すると、たとえば次のような攻撃シナリオが考えられます。

1.攻撃者がサイトAの運営を装い、悪意あるスクリプトを含んだURLを、キャンペーンメールなどに見せかけて送信します。

2.被害者がそのリンクを開くと、正規のサイトA上で攻撃者の用意したスクリプトが実行されます。

3.被害者がサイトAにログイン中だった場合、スクリプトによって利用者の情報や権限が悪用されるおそれがあります。

4.その結果、アカウントの不正利用や表示内容の改ざんなどにつながる可能性があります。

リンク先のFQDN自体は正規のサイトAのものです。そのため、メールの送信者名やドメインが本物に似ていれば、利用者がだまされてリンクを開いてしまうことも十分に考えられます。

※ FQDNとは、ホスト名やドメイン名などを省略せずに記述した完全なドメイン名のことです。

ここで取り上げた例は「反射型XSS」と呼ばれるものです。XSSにはほかにも、投稿内容などにスクリプトが保存される「格納型XSS」や、ブラウザ上のJavaScriptによるDOM操作が原因で発生する「DOMベースXSS」があります。

■XSSへの対策
基本的な対策は、入力された文字列をそのままHTMLとして出力しないことです。

具体的には、HTML上で特別な意味を持つ文字を、実体参照に変換してから出力します。

・< → &lt;
・> → &gt;
・" → &quot;
・& → &amp;

このように変換してから出力すると、HTMLは次のようになります。

<input type="text" value="パソコン&quot;&gt;&lt;script&gt;alert(&quot;危険です!&quot;)&lt;/script&gt;&lt;br style=&quot;">

この場合、scriptタグはHTMLタグとして解釈されず、単なる文字列として扱われます。そのため、スクリプトは実行されません。

ただし、XSS対策では「どの文脈に出力するか」が重要です。HTML本文、HTML属性、URL、JavaScript文字列、CSSなど、出力先によって必要なエスケープ方法は変わります。実際の開発では、テンプレートエンジンやフレームワークが提供するエスケープ機能を正しく使うことが大切です。

また、入力時に不要な文字種を制限することも一定の効果があります。ただし、入力制限だけでXSSを完全に防ぐことは難しいため、最終的には出力時の適切なエスケープを中心に考えるべきです。

■備考
XSSそのものへの対策とは少し異なりますが、攻撃による被害を小さくするための防御策もあります。

たとえば、セッションIDをJavaScriptから参照できないようにする HttpOnly 属性は有効な対策のひとつです。

Set-Cookie: session_id=b5dfb42eba3b872256a8dbbc29035b46; Path=/; Expires=Wed, 26 Oct 2018 09:00:00 GMT; Secure; HttpOnly

これは生のHTTPヘッダーの例です。実際の開発では、多くの場合、言語やフレームワークの機能を通じて設定します。

HttpOnly が設定されたCookieは、JavaScriptから参照できません。そのため、XSSが発生した場合でも、セッションIDを直接盗まれるリスクを下げることができます。

ただし、HttpOnly はXSSそのものを防ぐ仕組みではありません。XSSが残っていれば、利用者の権限で操作を実行されるなど、別の被害につながる可能性はあります。したがって、まずはXSSを発生させない実装を行い、そのうえで HttpOnly や Secure、SameSite などのCookie属性を組み合わせて防御を厚くすることが重要です。

■おわりに
XSSは、利用者の入力がそのままHTMLとして出力されてしまうことで、攻撃者のスクリプトが正規のサイト上で実行される脆弱性です。

対策の基本は、入力値を信用せず、出力する文脈に応じて適切にエスケープすることです。加えて、Cookie属性などの防御策を組み合わせることで、万が一の被害を小さくできます。