Simple XSS Prevention Method in Javascript
Tags: webdev, security, javascript, programming
Published: 2023-01-07 09:46:35

## About the content

 📌 This post includes a simple XSS prevention method on the javascript(express) server side. 

## Basics
XSS(Cross-site scripting) is most common vulnerability on the web applications. Most of the web applications have field like user input, login form, search etc. so the attackers can put the malicious javascript code in these input fields. Many information like user sessions can be stolen by proper input. There are some various of XSS like *Reflected XSS*, *DOM XSS* and *Stored XSS*, 
</br>
Anyways I am not going into deep detail about XSS so I guess you have sufficient knowledge so far.

---

## Code
Now it is time to show how to prevent on express API. Firstly the basic project should be created. The next we are going to create a vulnerable API structure using **Nodejs(Express.js)** and get the input from static login form file. 
</br>
You can follow the instructions below to create API easily.
Open the terminal and run the followings.

start the project
```bash
npm init -y
```
create a folder that will contain static files like html.
```bash
mkdir static
cd static
touch login.html
```
Go back to root directory and create a server file.
```bash
touch server.js
```
Install required packages.
```bash
npm install express body-parser
```
Time to configure and run out the API server in *server.js*.
```javascript
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();

app.use(bodyParser.urlencoded({ extended: false })); 
```
Get the login page while server is run
```javascript
app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '/static/login.html')); 
});
```
Create post request to get user information and run the server.
```javascript
app.post('/login', (req, res) => {
    res.status(200).send(
        "<div>" + req.body.username + " logged in!</div>"
    );
});

const PORT = '3000';

app.listen(PORT, () => {
    console.log(`listen on port: ${PORT}`);
});
```
Create the login form in *login.html*.
```html
<!DOCTYPE html>
<html>
  <head>
    <title>Example Login Form</title>
  </head>
  <body>
    <form action="/login" method="post">
      <!-- user input-->
      Username:<br />
      <input
        type="text"
        name="username"
        placeholder="Username"
        required
      /><br /><br />
      Password:<br />
      <input
        type="password"
        name="password"
        placeholder="Password"
        required
      /><br /><br />
      <!-- submit button -->
      <input type="submit" value="login" />
    </form>
  </body>
</html>
```
Run the server on terminal.
```bash
node server
```

👉 Checkout the **localhost:3000** on the browser and get to the login page like following.

![login_page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kfgfz8dgbdbkn3lzfjo.png)

If you get the same everything is well so far ! 👍
</br>
Enter username and password without any payload, server also returns username on the success page. 

Go back to login page and enter one of XSS payloads from following as username and also you can find more yourself.

![payloads](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wwfqvhsfc06gulgqjadf.png)

You are going to get an *alert* notification like this so the main thing is how to prevent it. 
![alert](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/is20nu3t7e93qmiqzjeh.png)

## Prevention Methods
Direct use of *res.send()* or *res.write()* might cause some problem like above. 

Alternatively, use *res.render()* instead however they are not the same methods. Sometimes you might need to use *res.send()* or *res.write()* methods therefore need to sanitize method.

</br>
Let's write a sanitizer over *String* class! Move on the bottom of *server.js* and define the function below. 
```
function onChangeString() {
    String.prototype.escape = function() {
        var tagsToReplace = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot',    
        };
        return this.replace(/[&<>"]/g, function(tag) {
            return tagsToReplace[tag] || tag;
        });
    };
}
```
Call the function like **onChangeString()** after package definitions and rewrite the post method using custom escape method that defined over String class.
```javascript
app.post('/login', (req, res) => {
    res.status(200).send(
        "<div>" + (req.body.username).escape() + " logged in!</div>" // prevent xss using String class based escape method 
    );
});
```
Check again on the browser and so you will see the payload as a string on the response.
![escaped](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/97kqt801ogr7ma7nv1zf.png)

Use of **escape** method detects some special entities from the string type user input. The main idea behind sanitization is escaping the some special characters like '<', '>', '"' or many of them. 

To check the entire project please visit my [Github](https://github.com/Bl4ckSt0n3/XSS_Prevention) account. 

Thank you for reading.
Have a nice day!