# Reflected

{% hint style="info" %}
**Reflected XSS** occurs when malicious scripts are reflected off a web server, executed immediately, and displayed in the user's browser, typically via URL parameters or form inputs.
{% endhint %}

{% hint style="danger" %}
This can lead to unauthorized actions, data theft, or redirection to malicious sites, as the script runs in the context of the trusted website.
{% endhint %}

## Reflected Server XSS

> *The example below is based on OffSec's* [*WEB-200*](https://www.offsec.com/courses/web-200/) *course.*

This type of XSS is often found in `GET` requests and is **based on the fact that the user trusts the domain**. The application below has a search functionality where the search term is passed through a `GET` request and the `s` parameter. It is also reflected on the page via a `div` element (Figure 1).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FznfpJEqLidVEAxWIvjy9%2Foffsec_xss_rs1.png?alt=media&#x26;token=3045ba77-33c1-4909-a21e-59ad6a03e562" alt=""><figcaption><p>Figure 1: Searching for potential XSS entry points.</p></figcaption></figure>

**A good starting point for finding XSS, is to first test for HTML injection** as it has less potential for error. However, being able to inject HTML doesn't guarantee an XSS vulnerablity (Figure 2).

```html
<!-- the HTML payload used -->
<h1>test</h1>
```

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FhIEn3qmnzG6Dy0kA7azv%2Foffsec_xss_rs1.png?alt=media&#x26;token=f05e7895-3071-4ec1-9605-7b9e47b4cf25" alt=""><figcaption><p>Figure 2: Testing for HTML injection.</p></figcaption></figure>

Since the app is vulerable to HTML injection, we can proceed testing for XSS (Figure 3).

```javascript
// the JavaScript payload used
<script>prompt("XSS")</script>
```

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FhNhMmnIVhmzEy2x7QSO9%2Foffsec_xss_rs3.png?alt=media&#x26;token=3f98cdee-06d1-4341-ad69-8ec1928c612a" alt=""><figcaption><p>Figure 3: Testing for XSS.</p></figcaption></figure>

If our target clicks the link that includes the payload, it will be executed on their browser.

```html
search.com/search.php?s=%3Cscript%3Eprompt%28%22XSS%22%29%3C%2Fscript%3E
```

In this case, **the server initiates the appending of the payload** (Figure 4) **and the client just executes it**.

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FpehPVhQiQ45QZOMCSPGA%2Foffsec_xss_rs4.png?alt=media&#x26;token=f6527317-f1d5-49e4-b8c7-a0989b9a0ed3" alt=""><figcaption><p>Figure 4: Confirming the server-side reflected XSS.</p></figcaption></figure>

## Reflected Client XSS

> *The example below is based on OffSec's* [*WEB-200*](https://www.offsec.com/courses/web-200/) *course.*

The impact of Reflected Client, aka ***DOM-based**,* XSS is similar to that of Reflected Server XSS, although the discovery and payload may differ. **The payload is appended on the client-side rather on the server-side**, and this mean that we can't enumerate Client XSS by intercepting the traffic and reviewing the server's response. Instead, we need to let the browser render the page fully and check if the payload has worked. The application we are testing includes a `GET` request with the parameter `name` which seems to be vulnerable to **HTML injection** (Figure 5).

```html
<!-- the HTML payload used -->
<h1>x7331</h1>
```

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FXRMTYwzLYz6YPLteLuqX%2Fweb_xss_reflected_client_1.png?alt=media&#x26;token=68a494cc-8945-4d3a-b177-8f7eddd13cb1" alt=""><figcaption><p>Figure 5: Testing for HTML injection.</p></figcaption></figure>

Testing for XSS seems unsuccessful, although the payload seems to be appended correctly (Figure 6).

```javascript
// the JavaScript payload used
<script>prompt("XSS")</script>
```

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FdtSYiIZKsiNz9FAsAw8q%2Fweb_xss_reflected_client_2.png?alt=media&#x26;token=8d991446-fcf7-44d6-8eba-de709374b728" alt=""><figcaption><p>Figure 6: Testing for XSS.</p></figcaption></figure>

Diving into the Network tab and reading the HTTP response, we can see that the string returned is `Welcome, User!` which is not what we get on our browser (Figure 7).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FJXRVt3TVti3nTfKs7oAc%2Fweb_xss_reflected_client_3.png?alt=media&#x26;token=16adb921-e309-4432-b150-2b92d9f72554" alt=""><figcaption><p>Figure 7: Inspecting the network tab.</p></figcaption></figure>

Scrolling down the JS file, we can find that two more resources are loaded (Figure 8).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2F5PhyT8plNjYMxDfdVjcT%2Fweb_xss_reflected_client_4.png?alt=media&#x26;token=85abdce0-38d0-4a0a-a3f1-cad534b03779" alt=""><figcaption><p>Figure 8: Enumerating JavaScript resources.</p></figcaption></figure>

Diving deeper into the `survey.js` file, we find out that it sets the `innerHTML` of the `welcome` DOM element to the value set in the `name` parameter. This is where our payload gets injected.

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2F3HNAxe8H3BXZfSMomlPo%2Fweb_xss_reflected_client_5.png?alt=media&#x26;token=10deabd2-2b9a-4a5a-ae1e-db3137b401c5" alt=""><figcaption><p>Figure 9: Investigating the <code>survey.js</code> file.</p></figcaption></figure>

According to [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations), HTML specifies that a `<script>` tag inserted with `innerHTML` should not execute and it suggests using the `<img>` tag instead (Figure 10).

```javascript
// the JavaScript payload used
<img src='x' onerror='alert(1)'>
```

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2F8zSZieYvN6FvDLnJKv4x%2Fweb_xss_reflected_client_6.png?alt=media&#x26;token=bbfa1eea-dfab-4d9d-955b-f7a3d97f5817" alt=""><figcaption><p>Figure 10: Successfully performing an XSS attack.</p></figcaption></figure>

## Filter Bypass

> *The example below is based on PortSwigger's* [*Reflected XSS into HTML context with most tags and attributes blocked*](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-html-context-with-most-tags-and-attributes-blocked) *lab.*

In this web application, there is a search functionality and the search term is reflected back into the page within HTML tags (Figure 11).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2F4mWs74n4kdrgz94VIhKM%2Fchrome_AdQrNSzgas.png?alt=media&#x26;token=040d750b-fe8b-4d5b-b552-7e4a36783b2f" alt=""><figcaption><p>Figure 11: Identifying where our input is reflected.</p></figcaption></figure>

When our payload is inside HTML tags, we can simply add new HTML tags to trigger it. It seems that there is a WAF[^1] blocking specific tags (Figure 12).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FpDfPFQJlxGJo7z4Ecz7n%2Fchrome_OWDqpOncf0.png?alt=media&#x26;token=48133bbd-975f-4c4d-b602-ec0a61fe4cb2" alt=""><figcaption><p>Figure 12: Common JavaScript tags seem to be blocked by a WAF.</p></figcaption></figure>

We can create a tag wordlist using PortSwigger's [XSS Cheatsheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet), and fuzz the application to see which tags are allowed (Figure 13).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FUW0utuGf1kY48HoFGYrc%2Fchrome_c5XiOX09Aq.png?alt=media&#x26;token=57e4f3f0-dd4a-4fc4-aea6-ceeccc29bd3c" alt=""><figcaption><p>Figure 13: Fuzzing JavaScript tags with Burp's Intruder.</p></figcaption></figure>

Trying the `<body>` tag results in another verbose error message (Figure 14).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FCfLI57UCBSopzh6vfHgO%2Fchrome_SsU7qmElJ3.png?alt=media&#x26;token=e422425b-1da0-458f-8179-6ae045da370f" alt=""><figcaption><p>Figure 14: Another verbose error message informing us about a blacklisted attribute.</p></figcaption></figure>

We can repeat the same process and enumerate allowed attributes (Figure 15).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FbOTVMrVYtMOjd6Fdnsos%2Fchrome_kTiOIYo53n.png?alt=media&#x26;token=4e22cd9e-cf6a-452c-8653-0a772bcac795" alt=""><figcaption><p>Figure 15: Fuzzing JavaScript attributes with Burp's Intruder.</p></figcaption></figure>

Now, all we have to do is delivering our XSS payload to the victim via the exploit server.

{% code overflow="wrap" %}

```javascript
// the JavaScript payload used
<iframe src="https://0a64008c03c63be4804ada980065007b.web-security-academy.net/?search=%3Cbody+onresize%3Dprint%28%29%3E" onload=this.style.width='1em'>
```

{% endcode %}

## Within JS

> *The example below is based on PortSwigger's* [*Reflected XSS into a JavaScript string with angle brackets HTML encoded*](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-angle-brackets-html-encoded) *lab.*

This time the search keyword ends up within a block of JS[^2] code (Figure 16).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2Fd7iTx9euuEw0XwnebDUB%2Fchrome_w3hihrXhZw.png?alt=media&#x26;token=d1d41c0c-150e-433b-a12c-a6778299621b" alt=""><figcaption><p>Figure 16: Identifying the context of a potential XSS flaw.</p></figcaption></figure>

We can treat this similar to an [SQLi](https://x7331.gitbook.io/boxes/web/injections/sqli/sqli-101) and try injecting JavaScript code to the search keyword (Figure 17).

<figure><img src="https://2056709691-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFqURPjUnKKhebI962QD8%2Fuploads%2FMGmysRJ6fN2j3kjUxudt%2Fchrome_tcQJlGe6UN.png?alt=media&#x26;token=0dd3ca54-1932-476b-adbf-775d4e2cf5a5" alt=""><figcaption><p>Figure 17: Achieving XSS via JavaScript Injection.</p></figcaption></figure>

[^1]: Web Application Firewall

[^2]: JavaScript
