あなたのWebサイトが「犯罪の道具」になる日
ある日、あなたの会社が運営するECサイトのお問い合わせフォームに、奇妙なメッセージが投稿されました。見た目は普通の問い合わせ文ですが、その裏にはブラウザへの「命令文」が紛れ込んでいます。管理者がそのメッセージを開いた瞬間、社内システムのログイン情報が攻撃者のサーバーに送信されてしまいました。
これがXSS(クロスサイトスクリプティング)の現実です。攻撃されるのはサーバーではなく、サイトを閲覧する「人のブラウザ」。そして加害者にされるのは、脆弱性を放置してしまった「あなたのサイト」です。
XSS(クロスサイトスクリプティング)の仕組みを3分で理解する
XSSとは、Webアプリケーションの「入力値をそのまま画面に表示する」という仕組みを悪用し、閲覧者のブラウザ上で不正なスクリプトを実行させる攻撃手法です。名前の由来は「クロスサイト(サイトをまたいで)スクリプト(プログラム)を実行させる」という意味ですが、実際には同一サイト内で完結するパターンも多く存在します。
攻撃の流れを整理すると、次のようになります。
① 攻撃者がスクリプトを仕込む → 掲示板、コメント欄、検索窓などにJavaScriptコードを入力します。
② サイトがスクリプトをそのまま出力 → サーバー側で入力値を無害化(サニタイズ)せずにHTMLとして出力します。
③ 被害者のブラウザで実行される → ページを表示した瞬間、埋め込まれたスクリプトが動き出し、Cookie窃取・フィッシング画面の表示・キーロガーの設置などが行われます。
ポイントは、攻撃対象がサーバーではなく「ブラウザ」であること。SQLインジェクションのようにデータベースが破壊されるのではなく、サイトを訪問したユーザーが一人ひとり被害に遭うのがXSSの特徴です。
XSSの3つの種類|反射型・格納型・DOMベースの違い
XSSは攻撃の経路によって3つのタイプに分類されます。それぞれ対策のアプローチが異なるため、正確に理解しておくことが重要です。
| 種類 | スクリプトの保存場所 | 攻撃の起点 | 典型的なシナリオ |
|---|---|---|---|
| 反射型(Reflected) | 保存されない(URLに含まれる) | 罠リンクのクリック | 検索結果ページにスクリプトが反映される |
| 格納型(Stored) | サーバーのDBに保存 | ページの閲覧だけで発動 | 掲示板の投稿にスクリプトが埋め込まれる |
| DOMベース | 保存されない(クライアント側のみ) | 罠リンクのクリック | JavaScriptがURLパラメータを直接DOMに挿入 |
反射型XSSは、攻撃者が作った不正なURLを被害者にクリックさせることで発動します。URLのパラメータにスクリプトを埋め込み、サーバーがそれをそのまま検索結果ページなどに反映する構造を悪用します。一度きりの攻撃で、リンクをクリックしない限り被害は発生しません。
格納型XSSは最も危険なタイプです。攻撃コードがデータベースに保存されるため、そのページを開いた全員が被害に遭います。SNSのプロフィール欄や口コミサイトのレビュー欄が狙われやすい対象です。
DOMベースXSSはサーバーを経由せず、ブラウザ上のJavaScript処理だけで完結する攻撃です。サーバー側のログに痕跡が残りにくいため、発見が困難という特徴があります。SPA(Single Page Application)の普及とともに増加傾向にあります。
XSSとCSRF・SQLインジェクションは何が違う?
Webセキュリティの脆弱性には似た名前のものが多く、混同しやすいのが実情です。ここでは代表的な3つの攻撃手法を比較します。
| 観点 | XSS | CSRF | SQLインジェクション |
|---|---|---|---|
| 攻撃対象 | ユーザーのブラウザ | ユーザーの認証済みセッション | サーバーのデータベース |
| 何を悪用するか | 入力値の出力処理の不備 | Cookieの自動送信の仕組み | SQL文の組み立て処理の不備 |
| 被害の例 | Cookie窃取、フィッシング | 意図しない送金・投稿 | データ漏洩・改ざん・削除 |
| 主な対策 | エスケープ処理、CSP | トークン検証、SameSite Cookie | プリペアドステートメント |
特にXSSとCSRFはセットで語られることが多いですが、XSSは「偽のスクリプトを実行させる」攻撃で、CSRFは「正規ユーザーになりすまして操作させる」攻撃という点で根本的に異なります。また、XSSが成功するとCSRFトークンも盗めてしまうため、XSSはCSRF対策すら無力化する上位の脅威とも言えます。
実務で必須の5つのXSS対策
XSS対策は「一つの対策で万全」とはなりません。多層防御(Defense in Depth)の考え方で、複数の対策を組み合わせることが重要です。
① 出力時のエスケープ処理(最重要)
HTMLに値を出力する際、< > & " ' の5文字をHTMLエンティティに変換します。これにより、ブラウザがスクリプトとして解釈することを防ぎます。出力先がHTML属性内、JavaScript内、URL内で変換ルールが異なる点に注意が必要です。
② Content Security Policy(CSP)の設定
HTTPレスポンスヘッダーでCSPを設定すると、許可していないドメインからのスクリプト読み込みをブラウザがブロックしてくれます。万が一エスケープ漏れがあっても、インラインスクリプトの実行を防ぐ「最後の砦」として機能します。
③ HttpOnly属性でCookieを保護
セッションCookieにHttpOnly属性を付与すると、JavaScriptからのCookieアクセスが禁止されます。XSSが成功してもセッションハイジャックを防げるため、被害を大幅に軽減できます。
④ 入力値のバリデーション
メールアドレス欄にはメールアドレスの形式のみ、電話番号欄には数字のみ、というように入力値を制限します。ただし、これは補助的な対策であり、自由記述欄(コメント欄など)では使えないため、エスケープ処理の代替にはなりません。
⑤ フレームワークの自動エスケープ機能を活用
React、Vue.js、Angularなどのモダンなフロントエンドフレームワークは、デフォルトで出力値をエスケープする仕組みを備えています。ただし、ReactのdangerouslySetInnerHTMLやVueのv-htmlのように明示的にエスケープを無効化するAPIもあるため、その使用箇所は厳重にレビューする必要があります。
よくある質問(FAQ)
Q. HTTPSを使っていればXSSは防げますか?
A. いいえ、防げません。HTTPSは通信の暗号化を担うものであり、XSSはサーバー側のアプリケーションの出力処理の問題です。HTTPSとXSS対策は、それぞれ別のレイヤーのセキュリティ施策です。
Q. WAF(Webアプリケーションファイアウォール)を導入すれば安心ですか?
A. WAFは既知の攻撃パターンをブロックする有効な手段ですが、新しい攻撃手法や巧妙にエンコードされたペイロードをすべて検知できるわけではありません。WAFに頼りきるのではなく、アプリケーション側でのエスケープ処理を基本対策として必ず実装してください。
Q. 自社サイトにXSS脆弱性があるか確認する方法は?
A. OWASP ZAPやBurp Suiteなどの脆弱性スキャナーを使った定期的な診断が効果的です。また、外部のセキュリティベンダーによるペネトレーションテスト(侵入テスト)を年1回以上実施することを推奨します。
まとめ:XSS対策は「出力のエスケープ」が出発点
XSSは、OWASP Top 10に長年ランクインし続ける代表的なWeb脆弱性です。攻撃の本質は「ユーザーの入力をそのまま出力してしまう」というシンプルな実装ミスにあり、逆に言えば出力時のエスケープ処理を徹底するだけで大半の攻撃を防ぐことができます。
ただし、DOMベースXSSのようにサーバーを経由しないパターンもあるため、CSPの導入やCookieのHttpOnly設定など、多層的な防御を組み合わせることが大切です。「うちは小規模なサイトだから大丈夫」という油断が最大のリスクであることを忘れないでください。

コメント