スクリプト・スタイル削除ルールの概要
HTML を「クリーニング/サニタイズ」するうえで最優先となるのが <script> と <style> 要素、および JavaScript イベント属性 (onclick など) の排除 です。これらを無効化することで XSS や意図しないレイアウト崩れを防ぎ、取得したマークアップを安全に下流処理へ渡せます。
1. 削除対象の定義
| 種類 | 具体例 | 既定ルール | 備考 |
|---|---|---|---|
| スクリプト要素 | <script>…</script>、<script src="…"> |
必ず削除 | src 属性の有無を問わない |
| スタイル要素 | <style>…</style> |
基本は削除 (ヘッダ内限定で許容する運用も可) |
|
| イベント属性 | onclick, onload, onerror, … |
必ず削除 | HTML5 で定義される全 70 種前後が対象 |
| style属性(インライン CSS) | style="color:red" |
サイト方針に応じて - 全部削除 - ホワイトリスト方式で一部残す |
allowlist にはセレクタ/プロパティ単位で正規表現を用意 |
2. HtmlAgilityPack での実装ステップ
以下は 最もシンプルな「全部削除」実装 です(.NET 8 で動作確認)。
-
XPath
"//script | //style"は DOM を 1 回で走査できコストが低い
(スクリプト削除コード例)htmlagilitypack.blogspot.com -
.Attributes.Remove は引数無しなら「そのノードの全属性削除」、
引数ありなら該当属性のみ削除できます。html-agility-pack.net
3. 高度なルール設定
| シナリオ | 例 | 実装アイディア |
|---|---|---|
ヘッダ内の <style> だけ残したい |
CSS カスタマイズを許可する CMS | //style[not(ancestor::head)] を削除対象に |
| CDN スクリプトを一部許可 | cdnjs.cloudflare.com/vue.min.js |
<script> を全削除後に手動で再注入または //script[not(@src='…')] |
| インライン style を部分許可 | font-weight, color のみ保持 |
正規表現で style 属性値からホワイトリスト外プロパティを除去 |
| 既存ライブラリを活用 | Vereyon/HtmlRuleSanitizer | HAP 上にルールエンジンを重ね、安全プロファイルを JSON で管理 github.com |
4. パフォーマンスと信頼性
-
逆順削除
foreach で Remove すると内部インデックスが壊れ一部ノードが残存することがあるため、必ず for 逆順か.ToList()でコピー後に削除する。htmlagilitypack.blogspot.com -
大規模文書対策
-
XPath を事前に
HtmlNodeNavigator.Compileして再利用 -
大量ページを並列処理する場合は
Parallel.ForEach+ スレッドローカル HtmlDocument
-
-
ユニットテスト
-
xUnit + ApprovalTests で「危険要素が 0 件」であることを自動検証
-
不正 HTML を含むケース(タグ未閉じなど)も含めて回帰テスト
-
5. まとめ
-
<script>と<style>は原則削除――最も簡単・安全なアプローチ。 -
イベント属性(onload など)は 属性レベルで必ず除去。
-
どうしてもスタイルを残したい場合は ホワイトリスト方式 を徹底し、
サニタイズ後に XSS 回帰テスト を必ず走らせる。 -
HtmlAgilityPack は「削除 API」自体はシンプルなので、ルール設計が肝。
運用ポリシーに合わせて XPath/正規表現/外部サニタイザを組み合わせることで、
安全かつ保守性の高いクリーニングパイプラインを構築できます。
ChatGPT4o 生成日:2025/06/23