# Yêu cầu
Tìm hiểu về lỗ hổng Cross-site Scripting (bao gồm khái niệm, các dạng tấn công, ví dụ mình họa, khái niệm về CSP, một số cách bypass CSP cơ bản)
- [x] Khái niệm
- [x] Các dạng tấn công và VD
- [x] Khái niệm CSP
- [x] Một số cách bypass CSP cơ bản
Hoàn thành 5 labs trên PortSwigger:
- [x] 2 labs Apprentice
- [x] 3 labs Practitioner
---
[ToC]
# What is cross-site scripting (XSS)?
:::info
:bulb: Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites
XSS attacks occur when an attacker uses a web application to send malicious code (generally in the form of a browser side script) to a different end user.
:::

An attacker can use XSS to send a malicious script to an unsuspecting user. The end user's browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious can access any cookies, session tokes, or other sensitive information retained by the browser and used with that site. These scrips can even rewrite the content of the HTML page.
## 3 Types of XSS
In 2005, these 3 types of XSS are defined as follow:
### Relected XSS (AKA Non-Persistent or Type I):

Reflected XSS occurs when user input is immediately returned by a web application in an error message, search result, or any other response that includes some or all of the input provided by the user as part of the request, without that data being made safe to render in the browser, and without permanently storing the user provided data. In some cases, the user provided data may never even leave the browser.
### Stored XSS (AKA Persistent or Type II):

Stored XSS generally occurs when user input is stored on the target server, such as in database, in a message forum, visitor log, comment field, etc. And then a victim is able to retrieve the stored data from the web application without that data being made safe to render in the browser.
### DOM Based XSS (AKA Type-0)

...
## 2 Types of XSS
For years, most people thougt of these (Stored, Reflected, DOM) as three different types of XSS, but in reality, they overlap. So to help clarify things, starting about mid 2012, the research community proposed and started using two new terms to help organize the types of XSS that can occur:
- Server XSS
- Client XSS
### Server XSS
Server XSS occurs when unstrusted user supplied data is included in an HTTP response generated by the server. The source of this data could be from the request, or from a stored location.
In this case, the entire vulnerability is in server-side code, and the browser is simply rendering the response and executing any valid script embedded in it.
### Client XSS
Client XSS occurs when untrusted user supplied data is used to update the DOM with an unsafe JavaScript call. A JavaScript call is considered unsafe if it can be used to introduce valid JavaScript into the DOM
# What is CSP (content security policy)?
CSP is a browser security mechnism 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
## Server-side handling of CSP:
### 1. Server configuration:
The website's server is responsible for generating and serving the HTTP response headers, which include the Content-Securtiy-Policy (CSP) header. The server administrator defines the CSP policy based on the specific security requirements of the website.
### 2. CSP policy derectives:
The server sets variouse directives within the CSP header to instruct the broser on what types of content to allow. These directives may include `default-src`, `script-src`, `style-src`, `img-src`, and many others, which define the allowed sourcces for different content types.
### 3. CSP reporting:
The server can also configure a separate endpoint to receive violation reports when the browser encounters content that violates the CSP policy. These reports provide valuable intormation about potential security issues and help administrators fine-tune the policy
## Browser-side handling of CSP:
### 1. Parsing the CSP header:
When the browser receives an HTTP response, it parses the CSP header to understand the policy defined by the server. The browser then applies this policy to the subsequent requests made by the webpage
### 2. Enforcing the policy:
The browser enforces the CSP policy by examining the sources of various content types (e.g., scripts, stylesheets, images, iframes) loaded by the webpage. If any content violates the policy, the browser blocks or modifies its behavior according to the defined directives
### 3. Reporting violations:
If the server has configured a reporting endpoint, the browser sends vilation reports to that endpoint whenever it encounters content that violates the CSP policy.

## Why CSP important?
### Mitigating Cross Site Scripting
The main purpose of CSP is to mitigate and dectect XSS attacks. XSS attacks exploit the browser's trust in the content received from the server. The victim's browser is exposed to execution of mailicious scripts, because the browser trusts the source of the content
CSP allows server administrators to reduce or eliminate the ability of an attacker to trigger XSS, by specifying which Internet domains browsers should consider as legitimate sources of executable scripts. CSP-compliant browsers only run scripts contained source files that are retrieved from whitelisted domains, and ignore all other scripts (including inline script and HTML event handling attributes)
### And more ...
## CSP Header Examples

### Fetch directive
CSO fetch directives are used in a Content-Security-Policy header and control locations from which certain resource types may be loaded. For instance, `script-src` allows developers to allow trusted sources of script to execute on a page, while `font-src` controls the sources of web fonts
All fetch directives fall back to `default-src`. That means, if a fetch directive is absent in the CSP header, the user agent will look for the `defautl-src` directive
[Here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#fetch_directives) for a complete list of fetch directives
### CSP source values
HTTP Content-Securtiy-Policy (CSP) header directives that specify a `<source>` from which resources may be loaded can use any one of the values listed below.
**`<host-source>`**: Internet host by name or IP address. The URL scheme, port number, and path are optional. Wildcards (`'*'`) can be used for subdomains, host address, and port number, indicating that all legal values of each are valid. When matching schemes, secure upgrades are allowed (e.g. specifying `http://example.com` will match `https://example.com`). Examples:
- `http://*.example.com`: Matches all attempts to load from any subdomain of example.com. Also matches `https:` resources.
- `mail.example.com:443`: Matches all attempts to load from port 443 on mail.example.com
- `https://stroke.example.com`: Matches all attempts to access store.example.com using `https:`
- `*.example.com`: Matches all attempts to load from any subdomain of example.com
- `https://*.example.com:12/path/to/file.js`: Matches all attempts to load from any subdomain of example.com, using `https:`, on port and only if the path is `/path/to/file.js`
- `ws://example.com`: Matches all attempts to load from example.com using `ws:`. Also matches `wss:`
**`<scheme-source>`**: A scheme such as `http:` or `https:`. The colon is required. Unlike ther values below, single quotes should't be used. You can also specify data schemes (not recommended)
- `data:` Allows `data:URLs` to be used as a content source. **This is insecure; an attacker can also inject arbitrary `data:`**
- `mediastream:` Allows `mediastream:URIs` to be used as a content source
- `blob:` Allows `blob` to be used as a content source
- `filesystem:` Allows `filesystem:` to be used as a content source
**`none`** Won't allow loading of any resources
**`'self'`** Refers to the origin from which the protected document is being served including the same URL scheme and port number. You must inlcude the single quotes. Some browsers specifically exclude `blob` and `filesystem` from source directives. Sites needing to allow these content types can specify them using the Data attribute
**`'unsafe-inline'`** Allow use of inline resources
**`'unsafe-eval'`** Allow use of dynamic code evaluation such as eval, setImmediate, and window.execScript
[Here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources) for a complete list of csp source values
## Someway bypass CSP
https://hacktricks.boitatech.com.br/pentesting-web/content-security-policy-csp-bypass#unsafe-scenarios
### EXPERT Lab: Reflected XSS protected by CSP, with CSP bypass
Here I try to inject a XSS payload, and got an error like this

It said:
> Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-bhHHL3z2vDgxUt0W3dWQOrprscmda2Y5pLsLg4GF+pI='), or a nonce ('nonce-...') is required to enable inline execution.
Check out CSP header

```
Content-Security-Policy:
default-src 'self';
object-src 'none';
script-src 'self';
style-src 'self';
report-uri /csp-report?token=
```
**`default-src 'self'`**: specifies that recsources should only be loaded from the same domain
**`object-src 'none'`**: specifies that no plugins or embedded object should be loaded onn the webpage. It effectively disables any plugins or objects on the page
**`script-src 'self'`**: specifies that JavaScript code should only be executed if it orjinates from the same domain. Scripts from external domains or inline scripts would be blocked
**`style-src 'self'`**: specifies that stylesheets should only be load from the same domain
**`report-uri /csp-report?token=`** specifies the endpoint where the browser should send violation reports when the CSP policy is violated. In this case the reports would be sent to the `/csp-reprot` endpoint with a token parameter
#### Bypassing CSP with Policy Injection
You may encouter a website that reflects input in to the actual policy, most likely in a `report-uri` directive. If the site reflects a parameter that you can control, you can inject a semicolon to add your own CSP directives.
Usually, this `report-uri` directive is the final one in the list. This means you will need to overwrite existing directives in order to exploit this vulnerability and bypass the policy.
Normally, it's not possible to overwrite an existing `script-src` directive. However Chrome recently introduced the `script-src-elem` directive, which allows you to control `script` elements, but not events.
Crucially, this new directive allows you to overwrite existing `script-src` directives.
Let's research a little bit about script-src-elem :thinking_face:
**`script-src`** specifies the locations from which a script can be executed from. It is a fallback directive for other script-like directives
- **`script-src-elem`**: controls the location from which execution of script requests and blocks can occur
- **`script-src-attr`**: controls the execution of event handlers
In this context, fallback means, if this directive (script-src-elem) is absent, the user agent will look for the script-src directive, and if both of the are absent, fall back to `defautl-src` directive
Now let's check if we can **Policy Injection** in this lab

After inject some inline script, the script was blocked by the browser and a POST request was sent to the server with empty `token` parameter :smiley:
So I tried to inject something in the `token` parameter and the site reflect it in the response

So if I inject a `script-src-elem` directive like this:
```
abc;scrip-src-elem 'unsave-inline'
```

My policy was injected into the response :smiley:
If the policy works, this time I can use an inline script, base on my policy `script-src-elem`

Bingo :sunglasses:
We can also have another attack using `script-src-attr`. We will insert the policy `script-src-attr 'unsafe-inline'` to enable the execution of the attributes. Then change the payload in search to `<img src/onerror=alert(1)>`

:::success
**Solved** :thumbsup:
:::
# Labs:
## Relected XSS
### APPRENTICE Lab: Reflected XSS into HTML context with nothing encoded
We got a website has a search function which receives the user-supplied search term in a URL parameter:

Then if our input is:
```htmlmixed=
</h1><script>alert('hacked!!');</script><h1>
```
The web app will add it in the HTML like this:
```htmlmixed=
<h1>0 search results for '</h1>
<script>alert('hacked!!');</script>
<h1>'</h1>
```
And the browser is simply rendering the HTML and executing any valid script embedded in it

:::success
**Solved** :thumbsup:
:::

### PRACTITIONER Lab: Reflected XSS into HTML context with most tags and attributes blocked
In this lab, we have been blocked from using some tags like this

I will use Burp Intruder to check if there are any unblocked tag that we can use. Send request to Intruder and insert a new payload marker like this

Next, we need to copy all `tag` from XSS cheat sheet then paste it in the Payload setting in the intruder's payload tab

Click Start attack, then check the response.

=> 2 tags are not blocked are `body` and `custom tag`
This lab also blocked some attribute, so we will need to check that too

=> There are 5 attributes we can use
- **`onbeforeinput`**: is tringgered just before the user's input is processed by the browser
- **`onbeforetoggle`**: fires on a popover element (i.e. one that has a valid popover attribute) just before it is shown or hidden.
- **`onratechange`**: is triggered when the playback rate of an audio or video element changes. It occurs when the user modifies the playback speed of the media
- **`onresize`**: is tringgered when the browser window or an element is resized
- **`onscrollend`**: is triggered when the user srolls the content of an element
We can use tag `body` and event attribute `onbeforeinput` to check if this web vulnerable to XSS
```htmlmixed=
<body onbeforeinput=alert(1)></body>
```
And when we try to enter any charater in the input box, alert message will appear

A note from this lab:

But all tags and attributes that we can use will need some trigger from the user, so we need to find another way :thinking_face:
There is also an exploit server to send an exploit to the victim

The idea now is when victim send a get request to exploit server, we will send back to them an HTML page with embedded blog page has XSS vulnerable, along with executable payload
```htmlmixed=
<iframe src="https://0a54004603838f07841a4017000c00c0.web-security-academy.net/?search=<body onresize=alert(1)></body>" onload=this.style.width='100px' >
</iframe>
```
This code will do 2 things:
1. Load the embedded blog with injected XSS payload
2. Use `onload` event to reload the page and style it with new different width. This will trigger XSS payload we have injected before
Add code to Body in Exploit server

Click View Exploit to see how it works, if we are the victim

Finally, click Store and click Delivery to the vitim, to send our exploit
Hmmm, still not solve :thinking_face:
This lab want me to call `print()` function so I will change it a little bit
```htmlmixed=
<iframe src="https://0a54004603838f07841a4017000c00c0.web-security-academy.net/?search=<body onresize=print()></body>" onload=this.style.width='100px' >
</iframe>
```
Now send it

:::success
**Solved** :thumbsup:
:::
### PRACTITIONER Lab: Reflected XSS into HTML context with all tags blocked except custom ones
I will use the same method in the previous lab to check which tags and attributes are allowed.
**Allow tags:**

**Allow attributes**

Seems like it not blocked any attributes :smiley:
So I try using the same payload in the previous lab to test xss vulnerable.
```htmlmixed=
<x onbeforeinput=alert(1)></x>
```
But it's not working :thinking_face:. Then I figured out
:::info
**`<body onbeforeinput>` :** When the `onbeforeinput` event is attached to the `<body>` element, *it captures input events that occur anywhere within the document body*. This includes input events within any child elements or custom tags contained within the `<body>`
**`<custom-tag onbeforeinput>` :** When the `onbeforeinput` event is attached to a custom tag, *it captures input events specific to that custom element only*. The event will not propagate to parent elements like the `<body>`
:::
So let's try another way. We can try using `onfocus` event by using it like this:
```htmlmixed=
<x tabindex=1 onfocus=alert(1)></x>
```
**`focus`** refers to the state of an element when it is actively selected or receiving user input. When an element is focused, it typically means that it is ready to accept user input, such as keyboard events or mouse clicks
**`onfocus`** is triggered when an element receives focus
**`tabindex`** attribute specifies the tab order of an element (when "tab" button is used for navigating)
Example:

The element that gets focus when the tab button is pressed will be W3Schools, Microsoft, Google respectively
So with above payload, we will get alert when the tab button is pressed

To avoid having to wait for the user to interact (waiting for the user to press the tab button) we can use the `autofocus` attribute
**`autofocus:`** If an element on the page has the `autofocus` attribute, it will receive focus automatically when the page loads. Only one element on the page can have the `autofocus` attribute, and it takes precedence over other factors
So with this payload
```htmlmixed=
<x autofocus tabindex=1 onfocus=alert(1)></x>
```
The alert pops up right after the page is loaded

Let's delivery payload to the user
First I try using `<iframe>` like previous lab, but it not working. Looks like the site doesn't allow us to embed it

Then I try using `<script> location`
```htmlmixed=
<script>
location="https://0a9c00d6039f7b3d8305419700e80021.web-security-academy.net/?search=%3Cx+autofocus+tabindex%3D1+onfocus%3Dalert%28document.cookie%29%3E%3C%2Fx%3E"
</script>
```

Now store it, and delivery it to the victim

:::success
**Solved** :thumbsup:
:::
### EXPERT Lab: Reflected XSS with event handlers and href attributes blocked
When testing for reflected and stored XSS, a key task is to identify the XSS context:
- The location within the response where attacker-controllable data appears
- Any input validation or other processing that is being performed on that data by the application
#### The location:

#### Input validation:
Check what tag we can use:

Check what event we can use:

Check if we can use `href` attribute:

Just like the description of this lab, this lab contains a reflected XSS vulnerability with some whitelisted tags, but all events and anchor `href` attributes are blocked
So I wonder if anchor `href` attributes are not blocked, what will the payload look like to be able to call the alert function
And I found an interesting way :smiley:
If you want to use the `href` attribute to trigger an alert dialog, achieve that by setting the href value to **`javascript:alert('Hello!');`**
Here's an example:
```htmlmixed=
<a href="javascript:alert('Hello!');">Click Me</a>
```
And if you don't know just like me, that when you type **`javascript:alert('hello');`** in your browser's search bar when browsing a web page.
Boom :boom: You get an alert box :smiley:

Back to our lab, cause we can't use anchor `href` let check out others element that we can use
Then I research about how `<svg>`, `<animate>` element work
**`<svg>`** is an HTML tag used to embed SVG content in a web page. SVG is a markup language for describing two-dimentsional vector graphics that can be rendered in web browser
Here is an example:
```htmlmixed=
<!DOCTYPE html>
<html>
<body>
<h1>The svg element</h1>
<svg height="130" width="500">
<rect x="50" y="50" width="100" height="100" fill="blue">
</rect>
</svg>
</body>
</html>
```

The above code uses the `<rect>` element to draw a rectangle with the attributes defined inside the element.
The SVG **`<animate>`** element provides a way to animate an attribute of an element over time
Here is an example:
```htmlembedded=
<!DOCTYPE html>
<html>
<body>
<h1>The svg element</h1>
<svg height="130" width="500">
<rect x="50" y="50" width="100" height="100" fill="blue">
<animate
attributeName="fill"
dur="2s"
repeatCount="indefinite"
values="blue;red;green;yellow;blue" />
</rect>
</svg>
</body>
</html>
```

The `<animate>` tag is used to animate the `fill` attribute of the rectangle. The `attributeName` is se to `fill`, indicating that the fill color will be animated.
The values attribute contains a list of colors separated by semicolons (;). Each color represents the fill color at a specific point in time during the animation
P/s: You can try to run the code to understand how it works
If you noticed, we just discovered a new way to use `href` instead of `<a href=` which is blocked :sunglasses:
Based on the two examples above,we can see that if we don't want to write it like this:
```htmlmixed=
fill="blue"
```
We can write it like this:
```htmlmixed=
<animate
attributeName="fill"
values="blue" />
```

Soooo :smirk:
If we can't use this
```htmlmixed=
<a href="javascript:alert('Hello!');"
```
We can use like this =))
```htmlmixed=
<svg>
<a>
<animate
attributeName="href"
values="javascript:alert('Hello!');" />
</a>
</svg>
```
And if we want to display text in SVG we can use **`<text>`** like this:
```htmlmixed=
<svg>
<a>
<animate
attributeName="href"
values="javascript:alert('Hello!');" />
<text x=20 y=20>
Click me
</text>
</a>
</svg>
```

:::success
**Solved** :thumbsup:
:::
### PRACTITIONER Lab: Reflected XSS with some SVG markup allowed
#### The location:

#### The validation:
Check what tag we can use:

Check what event we can use:

There are 4 tags we can use, I try using somepayload from this cheatsheet.

And it works :smiley:

Explain payload:
```htmlmixed=
<svg><animatetransform onbegin=alert(1) attributeName=transform>
```
**`<animatetransform>`** element animates a transformation attribute on its target element, thereby allowing animations to control translation, scaling, rotation, and/or skewing.
**`<onbegin>`** attribute is an event handler attribute that can be used with animation elements in SVG. It specifies a JavaScript function to be executed when the animation begins.
## Stored XSS
### APPRENTICE Lab: Stored XSS into HTML context with nothing encoded
We got a website allows users to submit comments on blog posts, which are displayed to other users.

Request:

It's a POST request, so the input must be store in database server then when we request again this page, the data we input will be render in the browser.
Let's try input this:
```htmlmixed=
<script>alert('hacked!!')</script>
```



:::success
**Solved** :thumbsup:
:::
## DOM-based XSS
### What is DOM?
DOM stands for Document Object Model.
**The DOM represents the web page as a hierachical tree structure**, where each element attribute, and text node is represented as an object. This tree-like structure allows developers to access, modify, and manipulate the elements and content of a web page.
### What is taint flow?
Taint flow, also known as information flow or data flow, refers to the tracking and analysis of data as it moves throuh a system or application. It involves identifying the origin of data (a source) adn tracking how it propagates and influences other parts of the system (sinks)
The concept of taint flow is commonly used in the context of security and vulnerability analysis.
### Sources
:::info
**A source** is a JavaScript property that accepts data that is potentially attacker-controlled.
:::
An example of a source is the `location.search` property because it reads input from the query string, which is relatively simple for an attacker to control.
Ultimately, any property that can be controlled by the attacker is a potential source. This includes the referring URL (exposed by the `document.referre` string), the user's cookies (exposed by the `document.cookie` string), and web messages.
### Sinks
:::info
**A sink** is a potentially dangerous JavaScript function or DOM object that can cause undesirable effects if attacker-controlled data is passed to it.
:::
For example, the `eval()` function is a sink because it processes the argument that is passed to ti as JavaScript.
An example of an HTML sink is `document.body.innerHTML` because it potentially allows an attacker to inject malicious HTML and execute arbitrary JavaScript.
### What is DOM-based XSS?
:::info
Fundamentally, DOM-based vulnerabilities arise **when a website passes data from a source to a sink** which then handles **the data in an unsafe way** in the context of the client's session
:::
### Exploiting DOM XSS with different sources and sinks
### APPRENTICE LAB: DOM XSS in `document.write` sink using source `location.search`

In here, we have a search function will display user input when performing a search like this

As usual I will try to perform Reflected XSS by trying to break out of `<h1>` tag

Looks like there's a mechanism in place to prevent an attempt to break out the `<h1>` tag. Check out source code, we can see that they have [encode data on output](https://portswigger.net/web-security/cross-site-scripting/preventing#encode-data-on-output). That's why our attempt failed.

But there is another place in HTML using our input

Let try to break out `<img>` tag with
```htmlmixed=
"><script>alert('hacked!!');</script>
```

**Bingo!!!** 🥳
#### Let's dive into the source code

**`window.location.search`** is typically used in JavaScript to retrieve the query string parameters from the current URL
For example, if the current URL is `"https://example.com/search?query=apple&page=1"`, then calling `window.location.search` will return `"?query=apple&page=1"`
**`.get()`** method is a function available in the URLSearchParams API in JavaScript. It is used to retireve the value of a specific query parameter from a URLSearchParams object
For example:
```javascript=
// Create a URLSearchParams object
var params = new URLSearchParams('?query=apple&page=1');
// Retrieve the value of a specific parameter using .get()
var query = params.get('query');
var page = params.get('page');
console.log(query); // "apple"
console.log(page); // "1"
```
And we can also clearly see it in our LAB

**`document.write`** method allows you to dynamically write content directly to the HTML document
That's why in source code, there is no `<img>` tag

But in the HTML structure rendered by browser, there is an `<img>` tag

And that's how data from a source to a sink can cause DOM-based XSS

:::success
**Solved** :thumbsup:
:::
### PRACTITIONER LAB: DOM XSS in `document.write` sink using source `location.search` inside a select element
This LAB don't have a search box like the LAB above

But when we click to a product, it send a query param to server, and in the source code, there is a script using **`window.location.search`** and **`document.write`**.

#### Let's dive into the source code to see if we can exploit anything here
After comparing the different between source code and HTML structure, we can comfirm that this script will generate select box on the site.

And here is what Chat GPT explains it for me :smiley:
```htmlmixed=
<script>
var stores = ["London","Paris","Milan"];
var store = (new URLSearchParams(window.location.search)).get('storeId');
document.write('<select name="storeId">');
if(store) {
document.write('<option selected>'+store+'</option>');
}
for(var i=0;i<stores.length;i++) {
if(stores[i] === store) {
continue;
}
document.write('<option>'+stores[i]+'</option>');
}
document.write('</select>');
</script>
```
1. The `stores` array contains three city names: "London", "Paris", and "Milan"
2. The code retrieves the value of the `storeId` parameter from the URL query string using the URLSearchParams and `get` methods.
3. It then dynamically generates the HTML for the dropdown menu using the **`document.write`** method.
4. If the value for `storeId` exists, it creates an `<option>` element with the selected value.
5. It iterates over the `stores` array and generates an `<option>` element for each city name, except for the one that matches the `storeId` value
6. Finally, it closes the `<select>` element.
And because it use `window.location.search` and method `get` so we can easily change data store in var `store` by sending a request with param `storeId` like this.

We can control the data from source **`location.search`** to sink **`document.write`** => Website vulnerable to DOM-based XSS. We will prove it by trying to break out `<option>` tag and calls the `alert` function
Payload:
```htmlmixed=
</option> <script>alert("hacked!!")</script>
```

**Bingo!!!** 🥳

:::success
**Solved** :thumbsup:
:::