Cross-site scripting (XSS) attack - Part 2
Tags: javascript, security
Published: 2021-07-22 21:09:20

In the last post I went through what is Cross-site scripting and Stored XSS attack, a type of cross-site scripting caused by stored javascript in database from user inputs. If you haven't read it, here is the [link](https://dev.to/ms_74/cross-site-scripting-xss-attack-part-1-3d9a). 

> As frontend developers we are constantly adding and releasing new features or fixing bugs as per business requirements, and it's hard to keep vigilance on the security side of things. It has become a secondary concern and we are far behind the backend and Devops engineers for whom this is a primary and regular part of their thinking in development process. Today security attacks are on the rise and we need to take measures from both server side and client side before its too late.

In this post I will go through another type of XSS attack and how to defend against it. 

## 2. Reflected Cross-site scripting attack

Suppose a webpage has a form page and on submission a HTTP request is made to check if the username exists. If the validation error then displays back the username entered within its error message, the hacker can take advantage of this vulnerability and enter a script into the input field. When the validation error message throws back the the error message with the script, the script gets executed. 
![Reflected xss](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ubt9weayo1minqijjeq9.png)

Another instance is when someone search for a search term, say *tesla* in their favourite search engine `https://www.dooble.com/search?q=tesla`.

![Search result for Tesla](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4k5iyjuohwwdwly9lw31.png)

 Imagine if the search term *tesla* displays above the search results extracted from the search term in the URL, a hacker can possibly replace the *tesla* parameter in the URL with malicious script, and have that script code execute whenever anybody opens that URL in their browser (Most search engines are possibly protected against this).
 An attacker could then email the URL with the malicious code as a link to a victim, or trick a user into visiting with the URL through a form. On clicking the link the user is then taken to the vulnerable web site, which reflects the attack back to the user’s browser. As it came from a “trusted” server, the browser executes the code.
 
When the injected script is reflected off the web server as above, we call this type of attack a **reflected cross-site scripting attack**. 


### Defence #1 - Again... Escape the content received from HTTP requests

The prevention for these type of attacks is again to escape the HTML by replacing its special characters with their corresponding entities.
![Again gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/atrzorsvcrk6zhhx5c1v.jpg)
Edit: **Note**: It is not just the HTML tag's inner content that needs encoding, but also the html attribute content `<div attr="...ENCODE UNTRUSTED DATA BEFORE PUTTING HERE...">content</div>`, quoted strings used within scripts like `alert('..text content..');`, quoted event handlers like `<div onmouseover="x='...ENCODE UNTRUSTED DATA BEFORE PUTTING HERE...'"</div>` and even CSS dynamic properties.

#### encodeURI
I mentioned earlier that most modern UI frameworks protects against XSS (make sure you read the security recommendations in the framework's documentation) and also about the javascript function `encodeURI()` that encodes URI's. 
This function encodes special characters except `,/?:@&=+$#'`.  
```
http://example.com/blog/1?comment=<script>alert(XSS1)</script>
```
```
http://example.com/blog/1?comment=%3Cscript%3Ealert(XSS1)%3C/script%3E
```

You may as well look into the function [encodeURIComponent()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) which encodes strings that is part of a URI. 

Both these functions does not escape the `'` (single quote) character, as it is a valid character for URIs.

The `'` character is commonly used as an alternative to `"`(double quote) for HTML attributes, e.g. href='MyUrl', which may introduce vulnerabilities. As it won't be escaped, input that includes it, will break the syntax resulting in an injection.

If you are constructing HTML from strings, either use `"` instead of `'` for attribute quotes, or add an extra layer of encoding (`'` can be encoded as %27).

Edit: **Note**: Avoid use of escaping like `\"` because the quote character runs first by the HTML attribute parser. This kind of escaping is vulnerable to `escape-the-escape` attacks where the attacker may add `\"` and the code will turn that into `\\"` which will ultimately enable the quote.

#### npm libraries
It is also recommended to use npm libraries like [xss-filters](https://www.npmjs.com/package/xss-filters) and [DOMPurify](https://github.com/cure53/DOMPurify) which provides filtering of unsafe characters.

```
const safeUsername = xssFilters.inHTMLData(unsafeUsername);
```
Note that `xss-filters` comes with some warnings, [read it here](https://www.npmjs.com/package/xss-filters#api-documentations).

When using validation on forms, try to use npm packages similar to [validator.js](https://github.com/validatorjs/validator.js) to sanitise the string inputs.
```
validator.escape(username); //replace <, >, &, ', " and / with HTML entities.
``` 

In the next post I will be going through the next type of XSS attack, *DOM based XSS attack* and how to defend against it. Stay tuned!