NodeJS Security for Beginners
Introduction:
NodeJS is an extremely powerful and lightweight technology, which is being widely adopted. Just like any other technology sometimes developers make mistakes during the development process, which may lead to serious vulnerabilities.
Learn Secure Coding
In this series of articles, we discuss various NodeJS specific and traditional vulnerabilities that we may come across when dealing with NodeJS apps.
Prerequisites:
This series of articles is going to walk the readers through various possible vulnerabilities in NodeJS code. So, a basic knowledge of writing simple NodeJS apps is required to practice the steps provided in these articles. If you just want to understand the concepts, then basic web application security knowledge is enough and we are good to go.
Getting started:
In all the articles in this series, we will have a close look at the vulnerable NodeJS source code. In this first article, let us discuss the infamous XSS vulnerability, and how to fix it.
When untrusted data is not properly sanitized by the application before displaying it back to the user, XSS occurs.
Below is a sample piece of code written in NodeJS and expression. This allows a user to insert some data through the input field and then echoes it back.
Vulnerable Code:
//This code is vulnerable to Cross Site Scripting
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.get('/', function(req, res){
var html = '' + '
'; res.send(html); }); app.post('/', function(req, res){ var userName = req.body.userName; var html = 'Hello: ' + userName + '.
' + ''; res.send(html); }); app.listen(8000);
The below piece of code is what makes the application vulnerable.
var userName = req.body.userName;
var html = 'Hello: ' + userName + '.
' +
'Try again.';
res.send(html);
As we can see, the user input is directly sent back to the user without any validation/encoding.
Let's run the application and see it in action.
When we enter some input into the application, it is going to echo it back to the user.
This looks as shown below.
Let us now test for Cross Site Scripting.
As expected, this is going to pop an alert box as shown below.
The source code of the response page is as shown below.
Fixing XSS using sanitizer:
Fixing XSS vulnerabilities in NodeJS application requires context specific output encoding just like any other web application. In the current example, we are going to use an npm module called "sanitizer".
First, make sure you download the npm module "sanitizer".
Once done with adding sanitizer module, the code used to fix is as shown below.
//Fixing XSS in nodejs apps using sanitizer
var express = require('express');
var sanitizer = require('sanitizer');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.get('/', function(req, res){
var html = '
'; res.send(html); }); app.post('/', function(req, res){ var userName = req.body.userName; var sanitizedinput = sanitizer.escape(userName); var html = 'Hello: ' + sanitizedinput + '. ' + 'Try again.'; res.send(html); }); app.listen(8000);
As we can see in the code above, we are making use of sanitizer for escaping the special characters from the user input before displaying it back to the user.
The following snippet from the above code shows how it is done.
var sanitizer = require('sanitizer');
.
.
.
.
var userName = req.body.userName;
var sanitizedinput = sanitizer.escape(userName);
var html = 'Hello: ' + sanitizedinput + '.
' +
'Try again.';
res.send(html);
Let us run this modified code with an XSS payload to see if the vulnerability persists.
If you notice, the malicious script inserted by the user has been output encoded and displayed back as data rather than code.
Source code of the response page is as shown below.
Additionally, we can add headers such as HttpOnly to minimize the attack surface.
Conclusion:
Learn Secure Coding
In this article, we have seen how traditional web vulnerabilities such as XSS can be a part of NodeJS applications. We have also seen the usage of sanitizer module. In the later parts of this series, we will see some other NodeJS specific as well as traditional vulnerabilities in NodeJS applications.