XSS 学習ノート
PayloadsAllTheThings、OWASP、MDN を参考に、XSS の攻撃面と防御チェックを実務向けに整理しました。
テスト方法
- まず出力コンテキストを確認します: HTML text、attribute、URL、JavaScript string、CSS、DOM sink、iframe wrapper。
- コンテキスト別 payload を貼り付け、実行有無とブロックした policy を記録します。
- 管理者画面、通知、メール、ログ、preview など遅れて描画される surface も確認します。
見落としやすい攻撃面
script tag だけでなく event handler、SVG onload、quote breakout も確認します。
href/src/action/data は正規化後に protocol allowlist で検証します。
location、hash、postMessage が innerHTML 等へ入ると DOM XSS になります。
保存形式ではなく最終 HTML を sanitize します。
host/protocol allowlist、sandbox、allow、referrer policy を一緒に設計します。
SVG/HTML upload と管理者 review は delayed stored XSS の典型です。
防御チェックリスト
- コンテキスト別出力 encoding と信頼できる sanitizer を組み合わせます。
- URL は正規化後に protocol/host allowlist で検証します。
- DOM sink は textContent や createElement など構造的 API に置き換えます。
- DOMPurify の許可 tag/attribute/URL policy を機能単位で文書化します。
- iframe は必要な host のみ許可し、sandbox を保守的に設定します。
- CSP は補助線であり sanitize の代替にはしません。
議論したい実際の悩み
ProseMirror の保存内容を別 renderer で表示し DOMPurify を適用しましたが、多様な embed provider を host allowlist で管理し続ける運用が現実的かが課題です。
profile field は小さく見えますが、attribute や custom renderer を通ると stored XSS が広がります。