Inline scenarios run automatically; external scenarios are triggered manually so you can attach breakpoints or observe the DOM mutations.
INLINE-1 (High): Auto-run from query/hash into innerHTML
// inline-script[#1]
(function(){
const target = 'inline-inner-html-target';
function render(content) {
if (content) innerHtmlSink(content, target);
}
const params = new URLSearchParams(location.search);
if (params.has('payload')) render(params.get('payload'));
})();
Waiting for payload…
INLINE-3 (Safe): Use textContent instead of innerHTML
// inline-script[#3]
(function(){
const params = new URLSearchParams(location.search);
const safe = params.get('safe');
const target = document.getElementById('inline-safe-target');
if (!target || !safe) return;
target.textContent = safe;
})();
Try ?safe=<img src=x onerror=alert(1)> to see the difference.
Waiting for safe payload…
Direct DOM sources → innerHTML
onclick="innerHtmlSink(location.hash, 'inline-inner-html-target')"
onclick="innerHtmlSink(getElementValue('target'), 'inline-inner-html-target')"
External innerHTML target (DOM sources)