Security in Node.JS and Express: The bare minimum - Part 1.
Petros Demetrakopoulos
Posted on April 6, 2020
Node.JS is one of the most famous frameworks for developing the back-end part of an application. However, this does not mean in any way that it does not contain many vulnerabilities that the developer should be aware and take actions in order to neutralize them.
What we will cover in this article
Server side JS injection
Also known as SSJS.
It is the case where user input is directly passed in native JS functions like eval()
,setTimeout()
, setInterval()
or Function()
. These functions enable the client to execute malicious Javascript code on the server-side. It could be a process.exit()
command that would kill the server or a call in file system. So we should simply avoid using these functions at any cost. These functions consist a bad practice even if we validate and sanitize user input data. In order to prevent it just use JSON.parse()
, it is much safer.
Use strict
"Use strict"
literal must be declared in the top of every JS script of our Node.JS application. It enables "strict mode" which does not allow some actions such as using a variable without declaring it (i.e x = 5.2
), deleting objects, variables, functions etc. It also limits eval()
use cases and possible exploits.
Helmet
Helmet is an npm package (you can install it by typing npm i helmet
) that sets various HTTP headers that may consist a threat if left with the default values. It sets Content-Security-Policy
header and it also allows the developer to set the X-Powered-By
header to other than the default value, so the intruder is not aware of real stack behind the application running on the server. Finally, it protects you from a bunch of other things like clickjacking and disables client-side caching.
Changing default error pages
There is no reason to hide X-Powered-By
header if we keep the default error pages of Express because the intruder can still understand that our server runs on Express. We can do so as shown in the snippet below:
// Handle 404
app.use(function(req, res) {
res.status(400);
res.render('404', {title: '404: File Not Found'});
});
// Handle 500
app.use(function(error, req, res, next) {
res.status(500);
res.render('500', {title:'500: Internal Server Error', error: error});
});
Proper session management
Session management may consist a possible threat too.
The Express cookies we user should always have these 2 properties always set to true
:
1) httpOnly
2) secure
The first one prevents cookies from being accessed by browser JS scripts and the second one forces that cookies can only be configured over secure HTTPS connections
The correct cookies setup is shown in the snippet below:
app.use(express.cookieParser());
app.use(express.session({
secret: "s3Cur3",
cookie: {
httpOnly: true,
secure: true
}
}));
ephemeral
cookie property is also very useul for security as it deletes the cookie when the browser is closed (if set to true
). So, it is very useful for apps that are being accessed by public computers.
Finally, we should always destroy session and cookies on logout.
Example:
req.session.destroy(function() {
res.redirect("/");
});
That's all folks (for now...)
I hope you find it interesting and it will help you build more secure and robust Node.JS and Express apps.
In the next part we will cover XSS Attacks, SQL and No-SQL injections and RegEx Denial of Service.
Part 2 is also available in the link below:
Posted on April 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.