Polyglot Payloads for Bug Bounty Testing
A polyglot is one input that remains meaningful under more than one parser or context. Hunters use them when a value moves through uncertain HTML, JavaScript, URL, JSON, or file-processing layers. They are good discovery tools. They are poor substitutes for understanding why execution happened.
The famous giant XSS string that triggers somewhere on a page can tell you a sink exists. Triage still needs the smallest payload for the actual sink.
Design from parser transitions
Write down the journey of the input. A search term might begin URL-encoded, enter JSON, get inserted into a JavaScript string, then land in HTML through innerHTML. Each transition adds escaping rules. A useful polyglot includes syntax that closes one context while remaining ignored or valid in another.
For example, quotes test string boundaries, angle brackets test HTML parsing, comment tokens suppress trailing syntax, and URL schemes test navigation sinks. Do not throw all characters together blindly. Add a unique marker around each boundary token and inspect the resulting DOM or response.
Browser DevTools shows the parsed DOM; “View Source” shows only the server response. For DOM XSS, the difference is often the whole bug.
Where polyglots earn their keep
Unknown reflection contexts are one case. Another is inconsistent rendering: the desktop app places a profile field in an HTML attribute while the mobile web view puts it inside a script object. A compact payload can flag both, then you split the proof into context-specific versions.
File polyglots exploit parser disagreement. A file may satisfy an image signature check while containing HTML, JavaScript, or archive structures another component interprets. Before testing one, map which parser sees the upload and how it is served. Content sniffing, forced download, and isolated origins often break the chain.
SQL and template polyglots can bridge dialects, but broad database payloads create noisy errors. Use boolean canaries and target the syntax revealed by the application rather than chasing a universal string.
Reduce after discovery
Once a polyglot fires, delete pieces until only the necessary grammar remains. This process answers valuable questions:
- Which decoder transformed the input?
- Which quote or delimiter ended the original context?
- Which parser treated the remainder as code?
- Which characters survived storage and re-rendering?
- Did a sanitizer mutate the payload into something more dangerous?
That final case is mutation XSS. A sanitizer may parse malformed markup one way, while the browser reparses serialized output another way. Capture both sanitizer output and final DOM.
WAF bypass without magic
Polyglots sometimes evade signatures because no single fragment looks complete to the edge, yet normalization or browser parsing joins it into executable syntax. Prove that sequence. A request returning 200 is not enough; demonstrate the final interpreter and safe effect.
Keep payloads short around production filters. Catastrophic backtracking, oversized multipart bodies, and parser bombs are not clever bypasses.
Write a report humans can debug
Include the initial polyglot as discovery evidence, then lead with the reduced payload. Mark encoding at each layer and state the exact context. Screenshots of an alert box help less than the response fragment, DOM node, and source-to-sink path.
Remediation should match the context: output encoding, safe DOM APIs, strict upload handling, parser alignment, or parameterized queries. Blocking your polyglot string merely creates a new signature.
PortSwigger's XSS context guide is a practical reference for parser boundaries. Think of a polyglot as a probe that asks several grammar questions at once, then slow down and answer the one that came back yes.