DEV Community

Cover image for Simple XSS Prevention Method in Javascript
Enes Karataş
Enes Karataş

Posted on

Simple XSS Prevention Method in Javascript

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,

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.

You can follow the instructions below to create API easily.
Open the terminal and run the followings.

start the project

npm init -y
Enter fullscreen mode Exit fullscreen mode

create a folder that will contain static files like html.

mkdir static
cd static
touch login.html
Enter fullscreen mode Exit fullscreen mode

Go back to root directory and create a server file.

touch server.js
Enter fullscreen mode Exit fullscreen mode

Install required packages.

npm install express body-parser
Enter fullscreen mode Exit fullscreen mode

Time to configure and run out the API server in server.js.

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();

app.use(bodyParser.urlencoded({ extended: false })); 
Enter fullscreen mode Exit fullscreen mode

Get the login page while server is run

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '/static/login.html')); 
});
Enter fullscreen mode Exit fullscreen mode

Create post request to get user information and run the server.

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}`);
});
Enter fullscreen mode Exit fullscreen mode

Create the login form in login.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>
Enter fullscreen mode Exit fullscreen mode

Run the server on terminal.

node server
Enter fullscreen mode Exit fullscreen mode

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

login_page

If you get the same everything is well so far ! 👍

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

You are going to get an alert notification like this so the main thing is how to prevent it.
alert

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.


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;
        });
    };
}
Enter fullscreen mode Exit fullscreen mode

Call the function like onChangeString() after package definitions and rewrite the post method using custom escape method that defined over String class.

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 
    );
});
Enter fullscreen mode Exit fullscreen mode

Check again on the browser and so you will see the payload as a string on the response.
escaped

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 account.

Thank you for reading.
Have a nice day!

Top comments (0)