XSS(クロスサイトスクリプティング)を初心者でも分かりやすく解説

検索窓に文字を入力しただけで、そのサイトを見た他のユーザー全員の情報が盗まれる──それがXSS(クロスサイトスクリプティング)です。Webサイトの入力欄に悪意のあるJavaScriptコードを注入し、サイトが適切に無害化せずに表示すると、訪問者のブラウザがそのコードを実行してしまいます。2018年のBritish Airways事件では、XSS脆弱性を悪用されて約38万件のクレジットカード情報が盗まれ、GDPRに基づく約24億円の罰金が科されました。Webサイト・APIの弱点として、反射型・格納型・DOM型の3つのタイプがあり、セッションハイジャック、フィッシング詐欺、マルウェア配布など被害は深刻です。2021年の調査では、Webアプリケーションの約40%に何らかのXSS脆弱性が存在すると報告されています。この記事では、XSSの仕組みと種類、実際の被害事例、そして入力のエスケープやCSP設定などの包括的なセキュリティ対策まで、初心者にも分かりやすく解説します。

XSS(クロスサイトスクリプティング)とは?

XSS(クロスサイトスクリプティング:Cross-Site Scripting)とは、Webサイトの入力欄やURL、掲示板などに悪意のあるスクリプト(主にJavaScript)を注入し、そのサイトを訪れた他のユーザーのブラウザで実行させる攻撃です。Webサイト・APIの弱点の中でも最も一般的で、影響範囲が広いセキュリティ脆弱性です。
XSSという略称は、本来CSS(Cascading Style Sheets)と混同を避けるために使われています。攻撃の本質は、Webサイトが入力されたデータを適切に処理せず、そのままHTMLとして出力してしまうことにあります。攻撃者は、検索窓、コメント欄、プロフィール編集、問い合わせフォームなど、ユーザーが自由に文字を入力できる場所に、通常のテキストではなくJavaScriptコードを入力します。
サイトがこの入力を適切に無害化(サニタイゼーション)せずにそのまま表示すると、訪問者のブラウザがそれを実行可能なコードと認識して実行してしまいます。その結果、訪問者のCookie(セッションIDなど)が盗まれる、偽のログインフォームが表示される、別のサイトに強制的にリダイレクトされる、マルウェアがダウンロードされるなどの被害が発生します。
XSSには主に3つのタイプがあります。「反射型XSS(Reflected XSS)」は、攻撃コードがURLに含まれており、そのリンクをクリックした瞬間に実行されます。「格納型XSS(Stored XSS)」は、攻撃コードがサーバーのデータベースに保存され、そのページを見たすべてのユーザーに影響します。「DOM型XSS」は、サーバーを経由せず、クライアント側のJavaScriptの処理の中で発生します。
Webサイト・APIの弱点として、XSSはOWASP Top 10(最も重大なWebアプリケーションセキュリティリスク)に常にランクインしており、2021年の調査では、Webアプリケーションの約40%に何らかの形でXSS脆弱性が存在すると報告されています。個人情報の窃取、アカウント乗っ取り、フィッシング詐欺、ウイルス感染など、被害は深刻です。

XSS(クロスサイトスクリプティング)を簡単に言うと?

公共の掲示板を想像してください。通常、人々は掲示板に文章を書き、それを読みます。しかし、悪意のある人物が、文章の代わりに「この紙を読んだ人は、自分の財布の中身を私に渡してください」という催眠術のような命令を書き込んだとします。そして、掲示板の管理者がそれをチェックせずにそのまま掲示してしまいました。
その命令を読んだ人々は、催眠術にかかったように指示に従ってしまいます。デジタルの世界では、Webサイトの入力欄に悪意のあるJavaScriptコード(ブラウザへの命令)を入力し、サイトがそれをチェックせずに表示すると、訪問者のブラウザがその命令を実行してしまいます。
「あなたのログイン情報を攻撃者に送信してください」「このフィッシングサイトに移動してください」「マルウェアをダウンロードしてください」といった命令が、信頼しているWebサイトを経由して実行されるため、ユーザーも、場合によってはセキュリティソフトも、正規の動作と区別がつきません。Webサイト・APIの弱点として、入力されたデータを無害化せずに表示してしまうことで発生する、極めて危険な脆弱性です。

XSS(クロスサイトスクリプティング)で発生する被害は?

XSS(クロスサイトスクリプティング)による被害は、攻撃者が実行するスクリプトの内容によって多岐にわたります。Webサイト・APIの弱点として、一つの脆弱性が多数のユーザーに影響を及ぼし、企業の信頼性を大きく損なう深刻なセキュリティ問題です。

XSS(クロスサイトスクリプティング)で発生する直接的被害

セッションハイジャックとアカウント乗っ取り

XSSの最も一般的な攻撃目的は、Cookie(特にセッションID)の窃取です。ユーザーがログインしているWebサイトでXSS攻撃を受けると、攻撃者が仕込んだJavaScriptがそのユーザーのCookieを読み取り、攻撃者のサーバーに送信します。セッションIDを入手した攻撃者は、パスワードを知らなくてもそのユーザーとしてログインでき、アカウントを完全に乗っ取ります。銀行サイトであれば送金、ECサイトであれば不正購入、SNSであれば友人への詐欺メッセージ送信など、あらゆる操作が可能になります。2018年、British Airwaysのウェブサイトで格納型XSSが悪用され、約38万件のクレジットカード情報が盗まれ、GDPRに基づく約24億円の罰金が科されました。

フィッシング詐欺とクレデンシャル窃取

XSSを使って、正規のWebサイト内に偽のログインフォームやポップアップを表示させることができます。ユーザーは信頼している正規サイトのURL上で偽フォームを見るため、疑うことなくパスワードやクレジットカード情報を入力してしまいます。通常のフィッシング詐欺では、URLが怪しいことで気づかれる可能性がありますが、XSSを使ったフィッシングでは、URLは正規サイトそのものであるため、極めて見破りにくくなります。2005年のMySpaceワーム「Samy」は、格納型XSSを利用して、わずか20時間で100万人以上のユーザーに感染し、プロフィールを改ざんしました。

マルウェア配布とドライブバイダウンロード

XSSを通じて、ユーザーのブラウザに悪意のあるファイルを自動的にダウンロードさせたり、マルウェア配布サイトにリダイレクトさせたりできます。ユーザーは信頼しているWebサイトを閲覧しているだけのつもりが、知らない間にウイルスやスパイウェアに感染させられます。特に、古いブラウザやプラグインを使用しているユーザーは、XSSと組み合わせた「ドライブバイダウンロード/マルバタイジング」により、何もクリックせずに感染することがあります。企業サイトが攻撃されると、その企業を信頼して訪問した多数の顧客が一斉にマルウェアに感染し、企業の評判は地に落ちます。

XSS(クロスサイトスクリプティング)で発生する間接的被害

企業の信用失墜と法的責任

WebサイトにXSS脆弱性が存在し、顧客が被害に遭った場合、企業は「セキュリティ対策が不十分」と非難され、信用を大きく損ないます。ニュースやSNSで拡散されれば、ブランドイメージは大きく傷つき、顧客離れが加速します。GDPRや個人情報保護法に基づく法的責任も発生し、適切なセキュリティ対策を怠っていた場合は巨額の罰金が科されます。集団訴訟のリスクもあり、復旧コスト、法的対応、広報活動、セキュリティ強化など、数億円から数十億円の損失が発生することもあります。上場企業の場合、株価にも直接影響します。

長期的な攻撃の踏み台と二次被害

格納型XSSは、攻撃コードがデータベースに永続的に保存されるため、脆弱性が修正されるまで、そのページを訪れるすべてのユーザーが被害を受け続けます。一日に数千人、数万人が訪れるサイトであれば、被害者の数は莫大になります。さらに、最初に感染したユーザーが、知らない間に他のユーザーへの攻撃を広める「ワーム」のような動作をすることもあります。SNSでは、XSSを使って自動的に友人に同じ攻撃リンクを送信させることで、指数関数的に被害が拡大します。

開発コストの増大と対応の遅れ

XSS脆弱性が発見されると、すべての入力箇所と出力箇所を調査し、修正する必要があります。大規模なWebアプリケーションでは、数百から数千の箇所をチェックしなければならず、膨大な時間とコストがかかります。緊急対応として、一時的にサービスを停止することもあり、ビジネス機会の損失も発生します。開発チームは通常業務を中断して対応に追われ、新機能の開発やビジネスの成長が遅れます。セキュリティ専門家への依頼、ペネトレーションテストの実施、コードレビューの強化など、追加のコストも必要です。

XSS(クロスサイトスクリプティング)の種類と対策

XSSは攻撃の方法によっていくつかの種類に分類され、それぞれ異なる特徴と対策が必要です。

反射型XSS(Reflected XSS)

最も一般的なタイプで、攻撃コードがURLやフォームのパラメータに含まれています。ユーザーが攻撃者が用意した悪意のあるリンクをクリックすると、そのパラメータがサーバーに送られ、サーバーが適切にエスケープせずにそのままHTML内に埋め込んで返します。ブラウザはそれをコードとして実行します。 例えば、検索機能で `https://example.com/search?q=

<script> 悪意のあるコード </script>

` というURLにアクセスすると、検索結果ページに「検索キーワード:

<script> 悪意のあるコード </script>

」と表示され、ブラウザがそのスクリプトを実行してしまいます。 反射型XSSは、攻撃者が被害者に悪意のあるリンクをクリックさせる必要があるため、フィッシングメールやSNSでリンクを拡散する手法と組み合わせて使われます。

格納型XSS(Stored XSS / Persistent XSS)

攻撃コードがサーバーのデータベースに保存され、そのデータが表示されるたびに実行される最も危険なタイプです。掲示板、ブログのコメント欄、プロフィール情報、レビュー投稿など、ユーザーが入力した内容がデータベースに保存され、後で他のユーザーに表示される場所が標的となります。
攻撃者は、コメント欄に悪意のあるスクリプトを投稿します。サイトがそれを適切にサニタイズせずにデータベースに保存し、他のユーザーがそのページを見ると、データベースから読み出されたスクリプトが実行されます。攻撃者は一度攻撃コードを投稿するだけで、その後そのページを訪れるすべてのユーザーが自動的に被害に遭います。
MySpaceワーム「Samy」や、多くのフォーラムやブログで発生した大規模な攻撃は、格納型XSSによるものでした。

DOM型XSS(DOM-based XSS)

サーバー側ではなく、クライアント側(ブラウザ)のJavaScriptコードの脆弱性を悪用するタイプです。サーバーのログにも残らないため、検知が困難です。 ブラウザがページをロードした後、JavaScriptがURLのフラグメント(#以降の部分)やその他のクライアント側データを読み取り、それをDOMに動的に挿入する際、適切にエスケープしないとXSSが発生します。 例えば、JavaScriptで `document.getElementById('output').innerHTML = location.hash;` というコードがあり、URLが `https://example.com/page#

<script> 悪意のあるコード </script>

` だった場合、そのスクリプトが実行されます。

XSS(クロスサイトスクリプティング)の対策方法

XSS(クロスサイトスクリプティング)の対策は、開発者側とユーザー側の両方で必要です。Webサイト・APIの弱点として、適切な実装と運用が不可欠です。
開発者側の基本対策として、入力値の検証(バリデーション)と出力時のエスケープ(サニタイゼーション)が最も重要です。ユーザーからの入力をそのままHTMLとして出力せず、特殊文字(`<`、`>`、`"`、`'`、`&`など)を無害な文字列(`<`、`>`など)に変換します。これにより、入力されたスクリプトはコードとしてではなく、単なるテキストとして表示されます。
コンテンツセキュリティポリシー(CSP)の実装により、ブラウザに「このサイトでは、どのソースからのスクリプトのみを実行するか」を指示します。適切に設定すれば、たとえXSS脆弱性があっても、攻撃者が注入したスクリプトは実行されません。HTTPヘッダーで `Content-Security-Policy: script-src 'self'` と設定すれば、同じドメインからのスクリプトのみが実行されます。
HTTPOnlyフラグをCookieに設定することで、JavaScriptからCookieにアクセスできなくなり、XSSでセッションIDが盗まれるリスクが大幅に減ります。認証に使うCookieには必ずHTTPOnlyフラグを設定すべきです。
フレームワークの適切な使用として、React、Vue.js、Angularなどの現代的なフレームワークは、デフォルトで出力を自動的にエスケープします。ただし、`dangerouslySetInnerHTML`(React)や`v-html`(Vue.js)のように、意図的にエスケープをバイパスする機能を使う際は、十分に注意が必要です。
ユーザー側の対策として、ブラウザとプラグインを最新版に保つことが重要です。古いブラウザには既知のXSS脆弱性が存在し、攻撃者に悪用されます。また、不審なリンクをクリックしない、信頼できないサイトで重要な情報を入力しないなどの基本的な注意も有効です。

XSS(クロスサイトスクリプティング)の対策を簡単に言うと?

レストランで料理を提供する際の衛生管理に似ています。お客様から食材を預かった場合(ユーザー入力)、それをそのまま提供するのではなく、必ず洗浄し(バリデーション)、適切に加熱処理して(エスケープ)から提供します。これにより、食材に混入していた有害な菌やウイルスを無害化します。
さらに、厨房では「この調理器具でのみ調理する」「この食材源からのみ仕入れる」というルールを設定します(CSP)。これにより、たとえ有害な食材が紛れ込んでも、調理過程で排除できます。また、最も重要な食材(Cookie)は、お客様が直接触れられない場所に保管します(HTTPOnly)。
近代的な調理システム(フレームワーク)を使えば、多くの安全処理が自動化されますが、特殊な調理法(dangerouslySetInnerHTML)を使う際は、熟練のシェフ(経験豊富な開発者)の監督が必要です。お客様側(ユーザー)も、衛生状態の悪いレストラン(信頼できないサイト)での食事は避けるべきです。Webサイト・APIの弱点への対策は、多層的な防御を組み合わせることが重要です。

XSS(クロスサイトスクリプティング)に関連した攻撃手法

XSS(クロスサイトスクリプティング)は、Webサイト・APIの弱点の中でも、他の攻撃手法と組み合わせて使われることが多い基本的な脆弱性です。
CSRFは、XSSと組み合わせると極めて強力な攻撃となります。CSRFでは、ユーザーが意図しない操作(送金、パスワード変更、商品購入など)を、ユーザーが気づかないうちに実行させます。通常、CSRFはCSRFトークンという防御機構で防げますが、XSSがあればこのトークンを読み取ることができます。XSSを使ってページ内のCSRFトークンを取得し、それを使ってCSRF攻撃を実行すれば、トークン検証を突破できます。つまり、XSSはCSRFの防御を無効化できる強力な手段です。両者ともWebサイト・APIの弱点として、XSSが「何でも実行できる」脆弱性であるのに対し、CSRFは「特定の操作を強制する」脆弱性です。XSSとCSRFを組み合わせることで、攻撃者はあらゆる防御をすり抜けて不正操作を実行できます。
クリックジャッキングは、XSSと類似した手法でユーザーを欺く攻撃です。クリックジャッキングでは、透明な iframe を本物のページの上に重ねて配置し、ユーザーが意図しないボタンやリンクをクリックさせます。XSSがJavaScriptコードを注入してブラウザに実行させるのに対し、クリックジャッキングはHTMLの視覚的なトリックでユーザーの操作を誤誘導します。XSSとクリックジャッキングを組み合わせると、XSSで偽のUI要素を動的に生成し、クリックジャッキングでユーザーの操作を乗っ取るという、より巧妙な攻撃が可能になります。両者ともWebサイト・APIの弱点として、ユーザーインターフェースを悪用してユーザーを騙すという共通点があります。対策も類似しており、XSSにはエスケープとCSP、クリックジャッキングにはX-Frame-OptionsとCSPのframe-ancestorsディレクティブが有効です。
オープンリダイレクトは、XSSの攻撃チェーンの一部として頻繁に使われます。オープンリダイレクトでは、WebサイトのリダイレクトURLを検証せずに使用することで、ユーザーを任意のサイトに誘導できます。XSSとオープンリダイレクトを組み合わせると、正規サイトのURLから始まるリンクでユーザーをフィッシングサイトに誘導できます。まずXSSでユーザーのCookieやセッション情報を盗み、次にオープンリダイレクトで偽のログインページに誘導してパスワードを入力させる、という多段階攻撃が可能です。両者ともWebサイト・APIの弱点として、ユーザー入力の不適切な扱いが根本原因です。XSSは「スクリプトを実行させる」、オープンリダイレクトは「別のサイトに誘導する」という違いがありますが、どちらも信頼されたサイトを悪用してユーザーを騙すという点で共通しています。

XSS(クロスサイトスクリプティング)のよくある質問

どちらも入力値の不適切な扱いによる脆弱性ですが、攻撃対象が異なります。SQLインジェクションはデータベースを攻撃し、データを盗んだり改ざんしたりします。XSSはブラウザ(ユーザー)を攻撃し、ユーザーのセッションを乗っ取ったり、フィッシングを仕掛けたりします。SQLインジェクションはサーバー側の問題、XSSはクライアント側の問題とも言えます。

エスケープは重要ですが、コンテキストによって適切なエスケープ方法が異なります。HTML内、JavaScript内、CSS内、URL内では、それぞれ異なる特殊文字をエスケープする必要があります。また、エスケープだけでなく、CSP、HTTPOnly、入力検証などの多層防御を組み合わせることが推奨されます。

セキュリティスキャナー(OWASP ZAP、Burp Suiteなど)を使った自動検査、ペネトレーションテストによる手動検査、バグバウンティプログラムでセキュリティ研究者に発見してもらう、ユーザーからの報告などがあります。コードレビューでも発見できますが、すべてを見つけることは困難です。

XSSは1990年代から知られていますが、Webアプリケーションが複雑化し、入力箇所が増え、新しいフレームワークや技術が登場し続けているため、新たな脆弱性が生まれ続けています。また、開発者のセキュリティ意識や知識の不足、納期優先でセキュリティが後回しにされることなども原因です。

これらのフレームワークはデフォルトで自動エスケープを行うため、基本的な使い方ではXSSのリスクは低いです。ただし、dangerouslySetInnerHTML(React)、v-html(Vue.js)、[innerHTML](Angular)など、意図的にエスケープをバイパスする機能を使う場合は、XSSのリスクがあります。フレームワークを使っていても、セキュリティ意識は必要です。

CSPは強力な防御層ですが、完全ではありません。設定ミス、古いブラウザでのサポート不足、CSP自体のバイパス手法などがあります。CSPは「最後の防御線」として機能しますが、入力検証とエスケープという基本対策が最優先です。多層防御の一部として使用すべきです。

ブラウザを最新版に保つ、不審なリンクをクリックしない、重要なサイトではブックマークからアクセスする、NoScriptなどのブラウザ拡張でスクリプト実行を制限する、パスワードマネージャーを使う(フィッシングサイトでは自動入力されない)などが有効です。ただし、根本的な対策はサイト運営者側で行う必要があります。

まず、脆弱性を修正するまで該当機能を一時停止するか、入力を厳しく制限します。すべての同様の箇所を調査して修正し、ペネトレーションテストで修正を確認します。被害が発生した可能性がある場合は、ユーザーに通知し、セッションをリセットし、パスワード変更を推奨します。再発防止のためにセキュアコーディングの教育も実施します。

はい、モバイルアプリ内でWebViewを使用している場合、XSSのリスクがあります。特に、ユーザー入力やサーバーからのデータをWebViewで表示する際、適切にエスケープしないとXSSが発生します。ネイティブアプリでもHTMLレンダリング部分では同様の注意が必要です。

XSRFはCSRF(クロスサイトリクエストフォージェリ)の別名です。XSSは「スクリプトを注入して実行させる」攻撃、CSRFは「ユーザーに意図しない操作を実行させる」攻撃です。XSSはJavaScriptを実行できるため、CSRFよりも強力で、CSRFの防御機構も突破できます。

極端な対策として、すべての特殊文字を拒否する方法もありますが、ユーザビリティが大きく損なわれます。名前に「O'Brien」のようなアポストロフィが含まれる、コメントで「<3」(ハート記号)を使いたい、など正当な使用例があります。適切なエスケープと検証のバランスが重要です。

はい、他人のWebサイトに悪意のあるコードを注入したり、ユーザーの情報を盗んだりする行為は、不正アクセス禁止法、コンピュータ詐欺法、個人情報保護法などに違反します。たとえ「セキュリティテスト」や「研究目的」であっても、許可なく行えば違法です。ホワイトハッカーとして活動する場合は、バグバウンティプログラムや正式な契約の下で行う必要があります。

更新履歴

初稿公開

京都開発研究所

システム開発/サーバ構築・保守/技術研究

CMSの独自開発および各業務管理システム開発を行っており、 10年以上にわたり自社開発CMSにて作成してきた70,000以上のサイトを 自社で管理するサーバに保守管理する。