filter-js-from-html について
HTMLの書式を保ちながら、JavaScriptやXSSの攻撃要素を除去するためのスキルです。フィルタリング方法、攻撃パターンの確認項目、検証手順を説明します。
主な機能
- 01書式保持を重視したフィルタリング
- 02多様なXSS攻撃パターンの網羅
- 03正規表現とパーサーの比較
- 04外部テストと無害な内容の検証
活用シーン
- 01HTMLからスクリプトやイベントハンドラーを除去
- 02危険なURL、CSS、SVGのフィルタリング
- 03除去後の安全性と書式の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ letta-ai/ skills --skill filter-js-from-htmlインストール後、Claude Code で/filter-js-from-htmlを入力して読み込まれたか確認します。
詳細
HTML から JavaScript を除去する
概要
このスキルでは、元の書式を正確に維持しながら、HTML コンテンツから JavaScript と XSS 攻撃ベクトルを除去する必要があるタスクの指針を示します。主な課題は、包括的なセキュリティフィルタリングと書式の維持を両立させることです。
重要な要件の分析
実装する前に、以下の要件を特定し、優先順位を付けてください。
- セキュリティの網羅性:すべての XSS 攻撃ベクトルを除去する必要があります
- 書式の維持:有害なコンテンツを除去する場合を除き、出力は入力と機能的に同一である必要があります
- クリーンなコンテンツの処理:XSS コンテンツを含まないファイルは、完全に変更せずに維持する必要があります
これらの要件はしばしば相反します。包括的な解析は書式を変更する可能性がある一方、単純な文字列置換では攻撃ベクトルを見逃すおそれがあります。
アプローチの選択
オプション 1:正規表現による外科的な除去(書式の維持に推奨)
元の書式を維持することが明示的に求められる場合は、危険なコンテンツだけを正確に除去する正規表現ベースのアプローチを優先してください。
利点:
- 空白、属性の順序、引用符のスタイルを正確に維持できます
- HTML の再構築や再フォーマットを行いません
- 除去したコンテンツを除き、入力と出力が文字単位で一致します
考慮事項:
- 部分一致を避けるため、パターンを慎重に構築する必要があります
- さまざまなエンコーディングや難読化手法に対応する必要があります
- 包括的な XSS 攻撃ベクトルの一覧に照らしてパターンをテストしてください
オプション 2:HTML パーサーベースのフィルタリング
書式の維持がそれほど重要でない場合や、不正な HTML を扱う場合に使用します。
考慮事項:
- HTML パーサーは本質的に出力を再構築するため、書式が変わります
- 属性の引用符、空白、タグの大文字・小文字が正規化されることがあります
- 正規表現では確実に解析できない不正な HTML に適しています
- このアプローチを使う場合は、クリーンな HTML ファイルが変更されずに維持されることを確認してください
包括的な XSS 攻撃ベクトルのチェックリスト
実装する前に、以下のすべての攻撃カテゴリを調査し、考慮してください。
1. スクリプト実行タグ
<script>タグ(属性付きのバリエーションを含む)<noscript>の悪用ケース
2. イベントハンドラー(網羅的な一覧が必要)
一般的なハンドラー:
onclick、onload、onerror、onmouseover、onfocus、onblur
見落とされやすいハンドラー:
onlayoutcomplete、ontimeerror、onselectionchangeonrowsinserted、onrowsdelete、onrowexit、onrowenteroncellchange、ondataavailable、ondatasetchanged、ondatasetcompleteonbeforeupdate、onafterupdate、onerrorupdateonfilterchange、onpropertychange、onreadystatechangeonbeforeprint、onafterprint、onbeforeunloadoncontextmenu、ondrag、ondragend、ondragenter、ondragleaveondragover、ondragstart、ondroponhashchange、oninput、oninvalid、onpageshow、onpagehideonpopstate、onresize、onstorage、onwheel
対応:記憶に頼らず、MDN や OWASP などの包括的なイベントハンドラー一覧を調べてください。
3. JavaScript URL プロトコル
- href、src、action、formaction、data、poster 属性内の
javascript: - 大文字・小文字のバリエーション:
JavaScript:、JAVASCRIPT:、JaVaScRiPt: - エンコードされたバリエーション:
javascript:、javascript:
4. その他の危険なプロトコル
vbscript:(IE のレガシー機能)- スクリプトコンテンツを含む
data:URI:data:text/html,<script>...</script> - エンコードされたペイロードを含む
data:text/html;base64,...
5. CSS ベースの攻撃
- 危険なプロパティを含む
<style>タグ -moz-binding(Firefox のレガシー機能)expression()(IE のレガシー機能)behavior:プロパティ- javascript または data URI を含む
@import
6. Meta タグ攻撃
<meta http-equiv="refresh" content="0;url=data:text/html,..."><meta http-equiv="refresh" content="0;url=javascript:...">
7. 外部リソースの読み込み
- 危険な href 値を持つ
<link>タグ - data 属性を持つ
<object>タグ - src 属性を持つ
<embed>タグ <applet>タグ(レガシー)- スクリプトを含む src または srcdoc を持つ
<iframe>
8. SVG ベースの攻撃
<svg onload="...">やその他の SVG イベントハンドラー<svg><script>...</script></svg>- 外部参照を使った SVG の
<use>
9. エンコーディングと難読化
- HTML エンティティエンコーディング:
<script> - URL エンコーディング:
%3Cscript%3E - UTF-7 エンコーディング攻撃
- ヌルバイトインジェクション:
<scr\0ipt> - Unicode の異体字
10. HTML コメントを悪用した攻撃
- 条件付きコメント:``
- 入れ子になったコメントの破壊
検証戦略
テストカテゴリ(すべて必須)
-
XSS 攻撃ベクトル
- 確立された XSS テストスイート(OWASP XSS Filter Evasion Cheat Sheet)を使用する
- 複数の手法を組み合わせた XSS ポリグロットをテストする
- あまり知られていないイベントハンドラーもテストに含める
-
フォーマットの保持
- さまざまな書式のクリーンな HTML ファイルを用意する
- クリーンなファイルの出力がバイト単位で完全に同一であることを検証する
- さまざまな空白パターン、引用符のスタイル、属性の順序をテストする
-
エッジケース
- 不正な形式の HTML
- 大文字と小文字が混在するタグおよび属性
- 引用符で囲まれていない属性
- 同じドキュメント内で複数のエンコーディングが使われているケース
テストプロセス
-
まず調査する:テストを作成する前に、以下を検索します。
- OWASP XSS Prevention Cheat Sheet
- XSS Filter Evasion Cheat Sheet
- 既知の XSS ポリグロット
- ブラウザー固有の攻撃ベクトル
-
攻撃者の視点に立ったテストを作成する:自分で作成したテストケースだけに頼らない
- 外部の包括的なテストスイートを使用する
- 過去にフィルターを回避した攻撃ベクトルを含める
-
クリーンなコンテンツが保持されることをテストする:セキュリティテストと同等の優先度で実施する
- 多様なクリーンな HTML サンプルを作成する
- 変更が発生しないことを検証する
- 空白、コメント、属性の順序を確認する
よくある落とし穴
1. イベントハンドラーのリストが不完全
間違い:onclick、onload、onerror など、よく使われるイベントハンドラーだけをハードコーディングする。
解決策:非推奨のものやブラウザー固有のものも含め、有効な HTML イベントハンドラーをすべて調査して含めます。
2. CSS 攻撃ベクトルを無視する
間違い:CSS ベースの XSS を無視して、JavaScript だけに注目する。
解決策:<style> タグ、危険な CSS プロパティ、expression を含む style 属性をフィルタリングします。
3. プロトコルハンドラーの見落とし
間違い:javascript: プロトコルだけをフィルタリングする。
解決策:vbscript:、危険なコンテンツを含む data: URI もフィルタリングし、エンコードされたプロトコル名にも対処します。
4. パーサーによるフォーマットの変更
間違い:フォーマットの保持が必要なのに HTML パーサーを使用する。 解決策:フォーマットの保持が重要な場合は、正規表現を使って対象を限定して除去するか、パーサーの出力が入力のフォーマットと一致することを検証します。
5. 自己検証型テスト
間違い:実際の攻撃ベクトルではなく、実装の能力に合ったテストケースを作成する。 解決策:セキュリティ研究者が作成した、外部の攻撃者視点のテストスイートを使用します。
6. 引用符とエンコーディングへの対処
間違い:属性内の HTML エンティティ("、')に対処しない。
解決策:属性内のエンコードされた文字が、どのようにフィルターを回避する可能性があるかを考慮します。
7. Meta refresh の見落とし
間違い:危険な URL を含む <meta http-equiv="refresh"> をフィルタリングしない。
解決策:フィルタリングの対象に meta タグを含めます。特に data: や javascript: URL を含むものが対象です。
8. 外部リソースを無視する
間違い:<link>、<object>、<embed> タグをフィルタリングしない。
解決策:これらのタグが危険なコンテンツを読み込んだり実行したりできるかどうかを評価します。
実装チェックリスト
実装が完了したと判断する前に、次の項目を確認してください。
- XSS 攻撃ベクトルの包括的な一覧を調査した
- すべてのイベントハンドラー(一般的なものだけでなく)をフィルタリングするよう実装した
- script タグおよび noscript の悪用に対処した
- javascript:、vbscript:、危険な data: URI をフィルタリングした
- CSS ベースの攻撃(style タグ、expression、binding)に対処した
- meta refresh 攻撃に対処した
- link、object、embed、applet タグを検討した
- SVG ベースの攻撃に対処した
- エンコードの違いを考慮した
- 外部の XSS テストスイートでテストした
- 安全な HTML ファイルが変更されずに保たれることを確認した
- 書式の保持(空白、引用符、順序)をテストした