実演動画あり!クロスサイト・スクリプティング(XSS)
目次
クロスサイト・スクリプティング(XSS)とは?
Webサイトが表⽰する画⾯には⼤きく分けて静的ページと動的ページの2種類の画⾯があります。静的ページは誰が閲覧しても常に同じ内容が表⽰される画⾯に対して、動的ページは閲覧するユーザーによって表⽰内容が変わる画⾯です。
後者の動的ページは利⽤者によって表⽰を変えているため、技術的にはWebページを表⽰する際にバックグランドのWebアプリケーションによって画⾯構成をユーザーに合わせて組み⽴てています。ただし、Webページの⽣成⽅法に問題があると、製作者が意図していない画⾯が表⽰されてしまうことがあります。
このような動的ページが意図していた画⾯と異なって表⽰されてしまう問題をクロスサイト・スクリプティング(XSS)と呼びます。またこの問題を悪⽤する⾏為をクロスサイト・スクリプティング(XSS)攻撃と呼びます。
クロスサイト・スクリプティング(XSS)攻撃の仕組み
サイバー攻撃は、Active Attack(能動的攻撃)とPassvie Attack(受動的攻撃)の2種類に分類されます。能動的攻撃は問題のあるWebサイトに直接攻撃を加える攻撃⽅法で、受動的攻撃は罠を仕掛けて被害に遭う利⽤者が現れるのを待つ攻撃⽅法となります。
クロスサイト・スクリプティング(XSS)攻撃は後者の受動的攻撃に分類され、罠の仕掛けられたリンクを被害者にクリックさせる、あるいは罠ページを閲覧させるなどの⾏為が起点となり、攻撃が成功すると以下のような被害を招きます。
セッション・ハイジャック
会員制のWebサイトに問題があった場合、ユーザーを追跡するために発⾏されたセッションIDがクロスサイト・スクリプティング(XSS)攻撃によって盗まれることがあります。
セッションIDが攻撃者の⼿に渡ると、攻撃者は被害者のログインIDやパスワードを知らなくとも、被害者になりすまして該当サイトに被害者としてアクセスすることが可能になるため、結果として重要情報の漏洩や該当サイトの不正操作といった被害を招きます。このような被害者のセッションIDを奪い、なりすましてアクセスすることをセッション・ハイジャックと呼びます。
偽ページの表⽰
クロスサイト・スクリプティング(XSS)は問題のあるWebページの画⾯構成に⼲渉する脆弱性であるため、悪⽤することで被害者に本来とは異なる内容のWebページを表⽰させることが可能です。
そのため、例えば会員機能のないサイトであっても架空のログイン画⾯を表⽰する、あるいは決済機能のないサイト上にクレジットカード情報の⼊⼒蘭を表⽰させるなど、攻撃者は被害者を巧妙に誘導することで秘匿情報を盗み出そうとします。
有害ファイルのダウンロード
クロスサイト・スクリプティング(XSS)攻撃が成⽴すると閲覧するだけでマルウェアなどの有害ファイルを強制的にダウンロードさせるWebページを表⽰させることが可能になります。
これは前述した通りクロスサイト・スクリプティングはWebページの画⾯構成を変更できるため、この特性を悪⽤して問題のあるWebページにリンク情報を追加するなどの改変を加えることで、閲覧したユーザーが気付かぬ内に有害ファイルをダウンロードするWebページにされてしまうといった事態を招きます。
不正なJavaScriptの実⾏
上記の代表的な被害以外にも、問題のあるWebページを閲覧すると暗号化通貨のマイニング処理(コンピュータに⾼負荷がかかる処理)が実⾏される、あるいはキーボードで⼊⼒した内容を秘密裏に外部サイトに送信するKey Logger(キーロガー:⼊⼒を監視するスパイウェア)の役割を果たす処理が実⾏されるなど、いずれも実害性の⾼い不正なJavaScriptプログラムが知らない間に動作していることがあります。
被害事例
以下のように世界的に有名なWebサイトであっても、過去にクロスサイト・スクリプティング(XSS)脆弱性が存在していたため、その問題を突いた攻撃によって被害を受けています。
PayPalでの被害事例
オンライン決済で世界的に有名なPayPalでは、2006年にクロスサイト・スクリプティング(XSS)攻撃でWebページが改変されフィッシング詐欺⾏為が⾏われていたことが発覚しました。なお被害の詳細は公表されていませんが、このクロスサイト・スクリプティング(XSS)は2年以上も放置されていた疑いがあり、細⼯が施されたリンクをクリックすると偽のオンライン決済ページが表⽰されていたとのことです。また同サービスでは被害は報告されていませんが、10年後の2016年にも別の箇所でクロスサイト・スクリプティング(XSS)脆弱性が発⾒され話題になりました。
Youtubeでの被害事例
2010年7⽉に⽶国でYoutubeがクロスサイト・スクリプティング(XSS)攻撃を受けました。この攻撃によりYoutubeは、著名な有名⼈の死亡説などショッキングなデマの拡散やコメント欄が荒らされるなど騒然とした状況に追い込まれました。提供元であるGoogle社はわずか2時間程度で同問題を修正しましたが、世界的に有名な動画共有サイトであるYoutubeがクロスサイト・スクリプティング(XSS)攻撃を受けて被害を出したことことに世界中が驚愕しました。
Twitterでの被害事例
2010年9⽉にTwitter上で発⾒されたクロスサイト・スクリプティング(XSS)の問題を悪⽤して、意味のわからないリツイートをばら撒くワーム(マルウェアの⼀種)が拡散されました。この事態に世界中のTwitterユーザーが騒然とした事例も有名です。ワームの製作者は少年であり実害性のあるコードが含まれていなかったため実害には⾄りませんでしたが、クロスサイト・スクリプティング(XSS)攻撃が与える影響を再認識させられた事件でもあります。
脆弱性の解説動画
クロスサイト・スクリプティング(XSS)が起こる原因
WebページはHTML(Hyper Text Markup Language)で画⾯が定義されています。HTMLとはデータ構造を定義するマークアップ⾔語のひとつで、扱うデータレベルはテキストデータ(アルファベットや数値、⽇本語など)です。またHTMLではWebブラウザに正しくデータ構造を伝えるためにタグ⽂字(<>:⼤なりや少なり)などの特殊⽂字を使ってマークアップ(強調)します。
そのため、例えばユーザーがタグ⽂字を含むデータを⼊⼒した場合、そのデータをそのまま利⽤して動的ページを⽣成してしまうとHTMLにおいて特殊性のあるタグ⽂字が有効な状態で出⼒されていまいます。その結果、製作者の意図したWebページではない別のページに置き換えられてしまうといった事態が発⽣します。このように何らかの外部⼊⼒が次画⾯以降のWebページのデータ構造に⼲渉してしまうことがクロスサイト・スクリプティング(XSS)の発⽣原因です。
またHTMLはscriptタグを⽤いてJavaScript⾔語を記述することができるため、クロスサイト・スクリプティング(XSS)の問題があると単純にWebページの構造を改変するだけではなく、JavaScript処理を外部から指定されてしまいます。
JavaScript⾔語はWebブラウザ上で動作するプログラム⾔語です。基本的なプログラム処理に加えてDocument Object Model(DOM)を通じて表⽰されているHTMLを操作したり、外部サイトとHTTP通信を⾏う、あるいは表⽰しているWebサイトから発⾏されたCookieやWebストレージのデータを読み込むなどの命令を実⾏することができます。
Webサービスの広がりに合わせて強化されてきたWebブラウザのSandbox機能(安全性を⾼める機能)によって⼀定の制限が設けられていますが、それでもJavaScriptを介して実⾏できる処理は、ある程度の⾃由度があるためクロスサイト・スクリプティング(XSS)脆弱性が存在すると、この特性を逆⼿にとって様々な攻撃が可能になります。
以下はクロスサイト・スクリプティング(XSS)が起こる典型的な攻撃例となります。
- 攻撃者は罠ページの公開や不正なリンクを含むメールを送信して罠を仕掛けます。
- 被害者が気付かずに罠ページを閲覧する、あるいはメールのリンクをクリックすることでXSS攻撃が発動します。
- 問題のあるWebサイトではエスケープ処理がされていないため、XSS攻撃で指定されたHTMLデータを利⽤して動的ページを⽣成し被害者に応答します。
- 被害者のWebブラウザ上でXSS攻撃を含むWebページが表⽰されることで、不正なJavaScriptが実⾏されます。
- 4までの⼿順で攻撃が成功すると攻撃者は被害者の機密情報などを奪取することができます。
少しややっこしいく感じるかもしれませんが、上記のようにサイトを経由してJavaScriptが実⾏されることから、クロスサイト・スクリプティング(サイトを経由してJavaScriptが実⾏される)脆弱性という名称が付けられました。
クロスサイト・スクリプティング(XSS)攻撃への対策⼿法
クロスサイト・スクリプティング(XSS)脆弱性が混⼊しないようにするためには、以下のような対策を実施する必要があります。
必須対策1(基本対策)
Webページを動的に⽣成する場合、以下の特殊性のある⽂字を参照⽂字に置換する処理(エスケープ処理)が必須となります。参照⽂字とはHTML上で特殊性のある⽂字をWebブラウザ上で表⽰したい場合に⽤いられる代⽤の⽂字のことです。
エスケープ処理の対象
名称 | 特殊文字 | 参照文字 |
大なり | > | > |
小なり | < | < |
アンパサンド | & | & |
ダブルクォーテーション | “ | " |
シングルクォーテーション | ‘ | ' |
上記のエスケープ処理は外部⼊⼒によって値の変更があるすべての箇所で実施する必要があります。Webアプリケーションで出⼒する全ての範囲が対象となることから対策漏れなどが発⽣しやすい傾向にあるため、注意が必要と⾔えます。
なお昨今、Webアプリケーションを構築する場合、サーバーサイドはフレームワーク(ある程度まとまったプログラム群)を利⽤して構築するケースが数多くあります。近年のメジャーなフレームワークで利⽤されているテンプレートエンジン(Webページを⽣成する機能)では、エンジニアが意識して上記のエスケープ処理を実装せずとも⾃動的にバックグランドで実⾏してくれます。そのため、新規でWebサイトを構築の際には、フレームワークが事前に⽤意してくれているエスケープ処理の恩恵を受けるために、利⽤するフレームワークのチュートリアルをご確認いただくことをお勧めいたします。
またWebページを表⽰する際にフロントエンドとバックエンドで分けているモダンな作りのWebサイトでは、フロントエンドのJavaScriptからDOM操作で表⽰を変更する際に、HTMLとして解釈されるinnerHTMLメソッドの使⽤を避けることが重要です。代わりに単純なテキストデータとして扱われるinnerTextメソッドを⽤いることで、⾃動的に上記のエスケープ処理がなされた状態で画⾯に出⼒することができます。
必須対策2(Webサイトの構成によって実施する対策)
HTMLで定義されている要素の中にはAタグやIMGタグなどURLを指定できるものがあります。この時、外部⼊⼒によってURLを出⼒する場合においては「http://」、および「https://」ではじまるURLのみを許可するチェック処理が必要となります。
これはURLには擬似スキーム(スキームとは資源への到達⽅法)という概念があるため、例えば「javascript:」から始まる⽂字列を指定するとWebブラウザはJavaScript⾔語を実⾏するスキームが指定されたと解釈し、以降の⽂字列をJavaScript⾔語のプログラムとして実⾏するからです。
また上記のHTML中の要素だけではなく、外部⼊⼒によって転送命令(リダイレクト)を指定する場合でも同様のチェック処理を⾏う必要があります。
推奨対策1(Webサイト設計時に考慮する対策)
HTML中に記述されるJavaScriptを動的に⽣成することは技術的に可能ですが、このような仕様のWebサイトではクロスサイト・スクリプトを含む脆弱性が混⼊しやすくなります。その結果、脆弱性対策の難易度が上がるため、可能な限りこのような仕様は避けることが望ましいとされています。
推奨対策2(Cookieにhttponly属性の付与)
Cookieを利⽤してセッション管理を⾏っており、かつセッションIDを格納しているCookieにJavaScriptからアクセスする必要がない場合のみに限定される推奨対策となります。Cookieには属性を付与することが可能で、このhttponly属性を付与するとJavaScriptを介して該当値にアクセスすることができなくなります。このことからクロスサイト・スクリプティング(XSS)脆弱性が存在した場合に、httponly属性が付与されていることで、その脅威を低減することができます。
オプショナルな対策(WAFの導⼊)
Webアプリケーションファイアーウォール(WAF)と呼ばれる製品を導⼊して、Webサイトを保護する⽅法です。この⽅法は⼀定の防御効果が⾒込めますが、製品を導⼊・運⽤していくのに費⽤が掛かることに加えて、理論上、すべてのクロスサイト・スクリプティング(XSS)攻撃を防御することができません。そのため、あくまで前述した必須対策が実施できない場合などに代価案として実施することが望ましい対策です。
まずは手軽にツールで脆弱性診断
上述の対策⼿法が重要となる⼀⽅で、脆弱性が混⼊されていないかを検知する事も重要となります。そのためには脆弱性診断を受診する必要があり、クロスサイト・スクリプティング(XSS)の脆弱性についても脆弱性診断を通じて発⾒する事が出来ます。
脆弱性診断とは何かについて詳しく知りたい方は脆弱性診断とは(エンジニア向け)と脆弱性診断とは(⾮エンジニア向け)もぜひご参照ください。
脆弱性診断ツール「Securify Scan」では、クロスサイト・スクリプティング(XSS)の脆弱性検知も対応しております。脆弱性検知やセキュリティレベルを強化したい企業様はぜひ弊社の脆弱性診断ツール「Securify Scan」を活用ください。
無償でのトライアル実施も行っておりますので、
お気軽にお問い合わせください。