4. Is the HTML content being interpreted by any client side JS engine (_AngularJS_, _VueJS_, _Mavo_...), you could abuse a [**Client Side Template Injection**](../client-side-template-injection-csti.md).
5. If you cannot create HTML tags that execute JS code, could you abuse a [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/)?
In order to successfully exploit a XSS the first thing you need to find is a **value controlled by you that is being reflected** in the web page.
* **Intermediately reflected**: If you find that the value of a parameter or even the path is being reflected in the web page you could exploit a **Reflected XSS**.
* **Stored and reflected**: If you find that a value controlled by you is saved in the server and is reflected every time you access a page you could exploit a **Stored XSS**.
* **Accessed via JS**: If you find that a value controlled by you is being access using JS you could exploit a **DOM XSS**.
When trying to exploit a XSS the first thing you need to know if **where is your input being reflected**. Depending on the context, you will be able to execute arbitrary JS code on different ways.
If your input is **reflected on the raw HTML** page you will need to abuse some **HTML tag** in order to execute JS code: `<img , <iframe , <svg , <script` ... these are just some of the many possible HTML tags you could use.\
1. To **escape from the attribute and from the tag** (then you will be in the raw HTML) and create new HTML tag to abuse: `"><img [...]`
2. If you **can escape from the attribute but not from the tag** (`>` is encoded or deleted), depending on the tag you could **create an event** that executes JS code: `" autofocus onfocus=alert(1) x="`
3. If you **cannot escape from the attribute** (`"` is being encoded or deleted), then depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked. Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**
4. If your input is reflected inside "**unexpoitable tags**" you could try the **`accesskey`** trick to abuse the vuln (you will need some kind of social engineer to exploit this): **`" accesskey="x" onclick="alert(1)" x="`**
In this case your input is reflected between **`<script> [...] </script>`** tags of a HTML page, inside a `.js` file or inside an attribute using **`javascript:`** protocol:
* If reflected between **`<script> [...] </script>`** tags, even if your input if inside any kind of quotes, you can try to inject `</script>` and escape from this context. This works because the **browser will first parse the HTML tags** and then the content, therefore, it won't notice that your injected `</script>` tag is inside the HTML code.
* If reflected **inside a JS string** and the last trick isn't working you would need to **exit** the string, **execute** your code and **reconstruct** the JS code (if there is any error, it won't be executed:
Javascript Hoisting references the opportunity to **declare functions, variables or classes after they are used so you can abuse scenarios where a XSS is using undeclared variables or functions.**\
Several web pages have endpoints that **accept as parameter the name of the function to execute**. A common example to see in the wild is something like: `?callback=callbackFunc`.
A good way to find out if something given directly by the user is trying to be executed is **modifying the param value** (for example to 'Vulnerable') and looking in the console for errors like:
In case it's vulnerable, you could be able to **trigger an alert** just doing sending the value: **`?callback=alert(1)`**. However, it' very common that this endpoints will **validate the content** to only allow letters, numbers, dots and underscores (**`[\w\._]`**).
However, even with that limitation it's still possible to perform some actions. This is because you can use that valid chars to **access any element in the DOM**:
You can also try to **trigger Javascript functions** directly: `obj.sales.delOrders`.
However, usually the endpoints executing the indicated function are endpoints without much interesting DOM, **other pages in the same origin** will have a **more interesting DOM** to perform more actions.
Therefore, in order to **abuse this vulnerability in a different DOM** the **Same Origin Method Execution (SOME)** exploitation was developed:
There is **JS code** that is using **unsafely** some **data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.
These kind of XSS can be found **anywhere**. They not depend just on the client exploitation of a web application but on **any****context**. These kind of **arbitrary JavaScript execution** can even be abuse to obtain **RCE**, **read****arbitrary****files** in clients and servers, and more.\
When your input is reflected **inside the HTML page** or you can escape and inject HTML code in this context the **first** thing you need to do if check if you can abuse `<` to create new tags: Just try to **reflect** that **char** and check if it's being **HTML encoded** or **deleted** of if it is **reflected without changes**. **Only in the last case you will be able to exploit this case**.\
For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
Once you have **located which tags are allowed**, you would need to **brute-force attributes/events** inside the found valid tags to see how you can attack the context.
Go to [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) and click on _**Copy tags to clipboard**_. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can **brute force all the events** using the valid tags (in the same web page click on _**Copy events to clipboard**_ and follow the same procedure as before).
If you didn't find any valid HTML tag, you could try to **create a custom tag** and and execute JS code with the `onfocus` attribute. In the XSS request, you need to end the URL with `#` to make the page **focus on that object** and **execute** the code:
**More tiny XSS for different environments** payload [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) and [**here**](https://tinyxss.terjanq.me).
If in order to exploit the vulnerability you need the **user to click a link or a form** with prepopulated data you could try to [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (if the page is vulnerable).
If you just think that **it's impossible to create an HTML tag with an attribute to execute JS code**, you should check [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/)because you could **exploit** the vulnerability **without** executing **JS** code.
If you are in **inside a HTML tag**, the first thing you could try is to **escape** from the tag and use some of the techniques mentioned in the [previous section](./#injecting-inside-raw-html) to execute JS code.\
If you **cannot escape from the tag**, you could create new attributes inside the tag to try to execute JS code, for example using some payload like (_note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag_):
Even if you **cannot escape from the attribute** (`"` is being encoded or deleted), depending on **which attribute** your value is being reflected in **if you control all the value or just a part** you will be able to abuse it. For **example**, if you control an event like `onclick=` you will be able to make it execute arbitrary code when it's clicked.\
Another interesting **example** is the attribute `href`, where you can use the `javascript:` protocol to execute arbitrary code: **`href="javascript:alert(1)"`**
The **HTML encoded characters** inside the value of HTML tags attributes are **decoded on runtime**. Therefore something like the following will be valid (the payload is in bold): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
There you can use the protocols **`javascript:`** or **`data:`** in some places to **execute arbitrary JS code**. Some will require user interaction on some won't.
**In general** the `javascript:` protocol can be **used in any tag that accepts the attribute `href`** and in **most** of the tags that accepts the **attribute `src`** (but not `<img`)
Moreover, there is another **nice trick** for these cases: **Even if your input inside `javascript:...` is being URL encoded, it will be URL decoded before it's executed.** So, if you need to **escape** from the **string** using a **single quote** and you see that **it's being URL encoded**, remember that **it doesn't matter,** it will be **interpreted** as a **single quote** during the **execution** time.
Note that if you try to **use both**`URLencode + HTMLencode` in any order to encode the **payload** it **won't****work**, but you can **mix them inside the payload**.
If you can inject any URL in an arbitrary **`<a href=`** tag that contains the **`target="_blank" and rel="opener"`** attributes, check the **following page to exploit this behavior**:
First of all check this page ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) for useful **"on" event handlers**.\
<buttonpopovertarget="newsletter">Subscribe to newsletter</button>
<divpopoverid="newsletter">Newsletter popup</div>
```
From [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): You can execute an **XSS payload inside a hidden attribute**, provided you can **persuade** the **victim** into pressing the **key combination**. On Firefox Windows/Linux the key combination is **ALT+SHIFT+X** and on OS X it is **CTRL+ALT+X**. You can specify a different key combination using a different key in the access key attribute. Here is the vector:
If you found a **XSS in a very small part** of the web that requires some kind of interaction (maybe a small link in the footer with an onmouseover element), you can try to **modify the space that element occupies** to maximize the probabilities of have the link fired.
For example, you could add some styling in the element like: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
But, if the WAF is filtering the style attribute, you can use CSS Styling Gadgets, so if you find, for example
This trick was taken from [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
In these case you **input** is going to be **reflected inside the JS code** of a `.js` file or between `<script>...</script>` tags or between HTML events that can execute JS code or between attributes that accepts the `javascript:` protocol.
Note that in this example we **haven't even closed the single quote**. This is because **HTML parsing is performed first by the browser**, which involves identifying page elements, including blocks of script. The parsing of JavaScript to understand and execute the embedded scripts is only carried out afterward.
If `<>` are being sanitised you can still **escape the string** where your input is being **located** and **execute arbitrary JS**. It's important to **fix JS syntax**, because if there are any errors, the JS code won't be executed:
In order to construct **strings** apart from single and double quotes JS also accepts **backticks****` `` `** . This is known as template literals as they allow to **embedded JS expressions** using `${ ... }` syntax.\
Therefore, if you find that your input is being **reflected** inside a JS string that is using backticks, you can abuse the syntax `${ ... }` to execute **arbitrary JS code**:
// Backtips pass the string as an array of lenght 1
alert`1`
// Backtips + Tagged Templates + call/apply
eval`alert\x281\x29` // This won't work as it will just return the passed array
setTimeout`alert\x281\x29`
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x281\x29`]}`
[].sort.call`${alert}1337`
[].map.call`${eval}\\u{61}lert\x281337\x29`
// To pass several arguments you can use
function btt(){
console.log(arguments);
}
btt`${'arg1'}${'arg2'}${'arg3'}`
//It's possible to construct a function and call it
Function`x${'alert(1337)'}x```
// .replace can use regexes and call a function if something is found
"a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a,"
"a".replace.call`1${/./}${alert}`
// This happened in the previous example
// Change "this" value of call to "1,"
// match anything with regex /./
// call alert with "1"
"a".replace.call`1337${/..../}${alert}` //alert with 1337 instead
// Using Reflect.apply to call any function with any argumnets
Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
// Using Reflect.set to call set any value to a variable
Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.
// valueOf, toString
// These operations are called when the object is used as a primitive
// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.
There is **JS code** that is using **unsafely data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.\
Also, don't forget that **at the end of the mentioned post** you can find an explanation about [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a **vulnerable subdomain to XSS**, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:
You can find a great abuse of this technique in [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
### Sending your session to the admin
Maybe an user can share his profile with the admin and if the self XSS is inside the profile of the user and the admin access it, he will trigger the vulnerability.
### Session Mirroring
If you find some self XSS and the web page have a **session mirroring for administrators**, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session.
You could make the **administrator trigger your self XSS** and steal his cookies/session.
You could check is the **reflected values** are being **unicode normalized** in the server (or in the client side) and abuse this functionality to bypass protections. [**Find an example here**](../unicode-injection/#xss-cross-site-scripting).
Due to **RoR mass assignment** quotes are inserted in the HTML and then the quote restriction is bypassed and additoinal fields (onfocus) can be added inside the tag.\
Form example ([from this report](https://hackerone.com/reports/709336)), if you send the payload:
If you find that you can **inject headers in a 302 Redirect response** you could try to **make the browser execute arbitrary JavaScript**. This is **not trivial** as modern browsers do not interpret the HTTP response body if the HTTP response status code is a 302, so just a cross-site scripting payload is useless.
In [**this report**](https://www.gremwell.com/firefox-xss-302) and [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.\
If you are able to indicate the **callback** that javascript is going to **execute** limited to those chars. [**Read this section of this post**](./#javascript-function) to find how to abuse this behaviour.
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) If you try to load a script with a **content-type** such as `application/octet-stream`, Chrome will throw following error:
> Refused to execute script from ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
The only **Content-Type**s that will support Chrome to run a **loaded script** are the ones inside the const **`kSupportedJavascriptTypes`** from [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third\_party/blink/common/mime\_util/mime\_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third\_party/blink/common/mime\_util/mime\_util.cc)
```c
const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};
```
### Script Types to XSS
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) So, which types could be indicated to load a script?
* [**webbundle**](https://web.dev/web-bundles/): Web Bundles is a feature that you can package a bunch of data (HTML, CSS, JS…) together into a **`.wbn`** file.
This behaviour was used in [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) to remap a library to eval to abuse it can trigger XSS.
* [**speculationrules**](https://github.com/WICG/nav-speculation)**:** This feature is mainly to solve some problems caused by pre-rendering. It works like this:
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) The following content types can execute XSS in all browsers:
In other browsers other **`Content-Types`** can be used to execute arbitrary JS, check: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
When something like **`"some {{template}} data".replace("{{template}}", <user_input>)`** is used. The attacker could use [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/String/replace#specifying\_a\_string\_as\_the\_replacement) to try to bypass some protections: ``"123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))``
For example in [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), this was used to **scape a JSON string** inside a script and execute arbitrary code.
If **everything is undefined** before executing untrusted code (like in [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)) it's possible to generate useful objects "out of nothing" to abuse the execution of arbitrary untrusted code:
* Using import()
```javascript
// although import "fs" doesn’t work, import('fs') does.
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) modules are wrapped by Node.js within a function, like this:
Therefore, if from that module we can **call another function**, it's possible to use `arguments.callee.caller.arguments[1]` from that function to access **`require`**:
In a similar way to the previous example, it's possible to **use error handlers** to access the **wrapper** of the module and get the **`require`** function:
* More sofisticated JSFuck: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce)
You **won't be able to access the cookies from JavaScript** if the HTTPOnly flag is set in the cookie. But here you have [some ways to bypass this protection](../hacking-with-cookies/#httponly) if you are lucky enough.
Review the list of ports banned in Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net\_util.cc) and in Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
When any data is introduced in the password field, the username and password is sent to the attackers server, even if the client selects a saved password and don't write anything the credentials will be ex-filtrated.
<!-- html5sec - eventhandler - element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known. -->
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
From [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) it's possible to learn that even if some values disappear from JS, it's still possible to find them in JS attributes in different objects. For example, an input of a REGEX is still possible to find it after the value of the input of the regex was removed:
If a web page is creating a PDF using user controlled input, you can try to **trick the bot** that is creating the PDF into **executing arbitrary JS code**.\
So, if the **PDF creator bot finds** some kind of **HTML****tags**, it is going to **interpret** them, and you can **abuse** this behaviour to cause a **Server XSS**.
AMP, aimed at accelerating web page performance on mobile devices, incorporates HTML tags supplemented by JavaScript to ensure functionality with an emphasis on speed and security. It supports a range of components for various features, accessible via [AMP components](https://amp.dev/documentation/components/?format=websites).
The [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) format extends specific AMP components to emails, enabling recipients to interact with content directly within their emails.
Learn & practice AWS Hacking:<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<imgsrc="/.gitbook/assets/arte.png"alt=""data-size="line">\
Learn & practice GCP Hacking: <imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<imgsrc="/.gitbook/assets/grte.png"alt=""data-size="line">](https://training.hacktricks.xyz/courses/grte)
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.