XSS Playground

Copy-and-test XSS scenarios

Sangmook Kim

AboutSangmook Kim

Frontend Engineer

I'm Sangmook Kim, a frontend developer. This site is not a product-specific PoC; it is an open playground for anyone who wants to verify XSS defenses in web services they own or are authorized to test.

Each scenario turns a realistic browser risk into a small test page: script tags, event-handler attributes, javascript: URLs, DOM sinks, embedded iframes, parent-window messaging, deceptive UI, and automatic requests.

Copy an HTML payload or iframe snippet from a scenario card or detail page, paste it into your own project, and check both the render result and the actual browser behavior.

GitHub

Caution. Only test services you own or have explicit permission to test. Probing third-party services may violate computer-misuse / unauthorized-access laws in your jurisdiction.

Project intent

XSS defense is not finished by naming an HTML filter or adding one line of filtering. You need to see what the browser actually allows across iframes, messages, permission prompts, automatic requests, and deceptive UI.

This site is not an attack automation tool. It is a repeatable checklist for developers and security teams testing rendering policies in services they own or are authorized to assess.

Every snippet is designed to be copied into a dev or staging environment. If an HTML payload executes or an iframe scenario works, it is a signal to investigate; if it is blocked, you can record which policy stopped it.

How to use

  1. Open a scenario page.
  2. Copy the HTML payload or iframe code from the home card or detail page.
  3. Paste it into your own service (editor, notes, wiki…) and save.
  4. Check rendering, sandbox behavior, CSP, postMessage validation, and the actual browser behavior.

XSS threat map

Based on the Hacker101 CTF XSS Playground categories and PortSwigger Web Security Academy guidance, this project groups the risks you should test into these areas.

Reflected XSS

Request data such as query strings, search terms, or error messages is immediately reflected into HTML without the right output encoding.

Stored XSS

Saved input such as comments, profiles, or document bodies is later rendered for other users as active content.

DOM-based XSS

Client-side code reads untrusted values from location, hash, postMessage, or storage and writes them into unsafe sinks like innerHTML or string-based timers.

Filter / CSP bypass

Event handlers, SVG/MathML, javascript: URLs, encodings, and template syntax can bypass weak blacklists or incomplete CSP rules.

Account abuse

Once script runs, it can act with the user's privileges, perform requests, manipulate the page, and access data the user can access.

Phishing / exfiltration

iframes, overlays, notifications, clipboard hooks, and postMessage can trick users into entering secrets or leak observable data out of the page.

Scenarios

Attack scenarios grouped by category. Copy an HTML payload or iframe embed directly from a card, or open a detail page for deeper testing.

HTML Injection

script tag injection

Check whether a raw script tag executes when user input is parsed as an HTML document.

<script>alert("xss-playground")</script>
Event-handler attribute injection

Check whether on* attributes such as img onerror or details ontoggle survive filtering and execute.

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

Check whether SVG, MathML namespaces, and event attributes bypass weak filters.

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

DOM XSS

DOM innerHTML sink

Check whether location, hash, postMessage, or other untrusted values reach unsafe sinks such as innerHTML.

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

URL / Protocol

javascript: URL protocol

Check whether javascript: remains in URL attributes such as href or action and executes on user interaction.

<a href="javascript:alert('xss-playground')">click me</a>

Navigation

top.location forced redirect

Replace the entire parent window from inside an iframe. The classic test for sandbox allow-top-navigation.

<iframe src="https://xss-playground.com/embed/top-redirect?lang=en" title="XSS Playground - top.location forced redirect" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Communication

postMessage spoofing

Send forged messages to the parent via parent.postMessage. If the parent skips event.origin validation, it can trust attacker-crafted payloads.

<iframe src="https://xss-playground.com/embed/post-message?lang=en" title="XSS Playground - postMessage spoofing" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Hidden form auto-submit (CSRF-style)

Submit a form to a third-party endpoint without user input.

<iframe src="https://xss-playground.com/embed/form-auto-submit?lang=en" title="XSS Playground - Hidden form auto-submit (CSRF-style)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
sendBeacon / fetch exfiltration

Exfiltrate everything observable inside the iframe to an attacker server.

<iframe src="https://xss-playground.com/embed/beacon-exfil?lang=en" title="XSS Playground - sendBeacon / fetch exfiltration" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
img tag GET request CSRF

The oldest CSRF: img.src to a state-changing GET endpoint sends cookies along.

<iframe src="https://xss-playground.com/embed/csrf-image?lang=en" title="XSS Playground - img tag GET request CSRF" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Exfiltration

Parent token / network exfiltration attempts

Multi-angle attempts to extract JWT, in-flight network, or storage from the parent. See exactly what SOP blocks and what slips through.

<iframe src="https://xss-playground.com/embed/token-exfil?lang=en" title="XSS Playground - Parent token / network exfiltration attempts" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Phishing

Fake login form (phishing)

Show a form that looks identical to the parent site's login UI and exfiltrate the credentials.

<iframe src="https://xss-playground.com/embed/phishing-form?lang=en" title="XSS Playground - Fake login form (phishing)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Fullscreen overlay impersonation

Cover the parent page with a fake but pixel-perfect UI rendered inside the iframe.

<iframe src="https://xss-playground.com/embed/fullscreen-overlay?lang=en" title="XSS Playground - Fullscreen overlay impersonation" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Delayed / Chained

Delayed / auto-fire payload

Countdown via URL params, then auto-fire an action. Used to evade immediate user suspicion.

<iframe src="https://xss-playground.com/embed/delayed-attack?lang=en" title="XSS Playground - Delayed / auto-fire payload" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Chained attack (phishing + fullscreen + redirect)

Fullscreen fake UI → credential capture → top redirect to the real site to cover tracks.

<iframe src="https://xss-playground.com/embed/chained-attack?lang=en" title="XSS Playground - Chained attack (phishing + fullscreen + redirect)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Annoyance

Auto-download trigger

Force a file download without any user click.

<iframe src="https://xss-playground.com/embed/auto-download?lang=en" title="XSS Playground - Auto-download trigger" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
popup / window.open spam

Open new windows. Same-origin popups can host arbitrary phishing UI.

<iframe src="https://xss-playground.com/embed/popup-spam?lang=en" title="XSS Playground - popup / window.open spam" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Autoplay media / forced fullscreen

Autoplay sound video, call requestFullscreen, and observe what gets through.

<iframe src="https://xss-playground.com/embed/autoplay-media?lang=en" title="XSS Playground - Autoplay media / forced fullscreen" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Notification permission / push hijack

Trigger Notification.requestPermission so the attacker domain can later push notifications.

<iframe src="https://xss-playground.com/embed/notification-permission?lang=en" title="XSS Playground - Notification permission / push hijack" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Clipboard hijack

Intercept the copy event and overwrite clipboard contents.

<iframe src="https://xss-playground.com/embed/clipboard-hijack?lang=en" title="XSS Playground - Clipboard hijack" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
history.pushState pollution

Push a flood of history entries to wreck the parent's back-button behavior.

<iframe src="https://xss-playground.com/embed/history-pollution?lang=en" title="XSS Playground - history.pushState pollution" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Probe

Same-Origin Policy probe (what is blocked)

Try to reach parent.document, parent.localStorage, parent cookies — confirm what SOP actually blocks.

<iframe src="https://xss-playground.com/embed/sop-probe?lang=en" title="XSS Playground - Same-Origin Policy probe (what is blocked)" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
Parent message-listener fingerprinting

Fire a wide range of postMessage payloads at the parent and observe responses or side effects.

<iframe src="https://xss-playground.com/embed/parent-message-listener-probe?lang=en" title="XSS Playground - Parent message-listener fingerprinting" width="600" height="420" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>

Contributing (Issues / PRs)

This project is source-available, not open-source. The code is public for review and contributions, but forking the project to run a separate deployment, mirror, or commercial service is not permitted.

Ideas, bug reports, translation fixes, and new scenarios are welcome. Open an Issue first; if the change is accepted in principle you can be added as a collaborator and push a branch directly to this repository instead of a long-lived fork.

Full policy lives in LICENSE and CONTRIBUTING.md.