At Software Secured, we have been building our internal tools around Node.js and Express. Node.js is becoming more and more popular nowadays and several frameworks have popped up to wrap Node.js functionality and APIs. One of these frameworks is Express JS. Express is very popular today as it was one of the first frameworks for Node.js that handled server-side web tasks. It takes care of mundane tasks, like routing, parameter parsing, templates, and sending responses to the client's browser. Node.js make it easier to develop secure applications using Express JS; there are a bunch of security features that can be enabled easily by making simple modifications. The following contains a quick rundown of these features.
This is super easy to setup. We use the lusca module. The code looks something like this:
[code]var express = require('express');
var session = require('express-session');
var app = express();
var csrf = require('lusca').csrf();
...
app.use(lusca.csrf());[/code]
This is then used in the forms that post to the server:
[code]form(role="form" action="..." method="post")
input(type='hidden' name='_csrf' value=_csrf)
...[/code]
It’s been long foretold by the ancient bearded ops that one shall run a service with the least amount of privilege necessary and no more.
One way to approach this is to drop process privileges after you bind to the port using something like this:
[code]var express = require('express');
var app = express();
...
app.listen(app.get('port'), function() {
process.setgid('www-data');
process.setuid('www-data');
});[/code]
Another way is putting something like nginx or another proxy in front of your application. Whatever you do, just don’t freak’n run as root.
Why? Because you don’t want to make it easy for an attacker to figure what you are running The X-Powered-By header can be extremely useful to an attacker for building a site’s risk profile
X-Powered-By: Express
Can be removed using:
[code]var express = require('express');
var app = express();
...
app.disable('x-powered-by');[/code]
One way to fingerprint your application is using the cookie name.
jsessionid -> Java application
phpsessid -> PHP application
ASP.NET_SessionId -> .net application
This is again a technique to hide information about what technology is being used.
[code]app.use(express.session({
secret: 'some secret that now one knows',
key: 'sessionId'
}));[/code]
Session cookies should have the SECURE and HTTPOnly flags set. This ensures they can only be sent over HTTPS (you are using HTTPS, right?) and there is no script access to the cookie client side.
[code]app.use(express.session({
secret: "s3Cur3",
key: "sessionId”,
cookie: {
httpOnly: true,
secure: true
}}));[/code]
This header is implemented in a select set of browsers at the moment, but still helps towards fending off attacks.
[code]var express = require('express');
var helmet = require('helmet');
var app = express();
...
app.use(helmet.contentSecurityPolicy({
defaultSrc: ["'self'", 'default.com'],
scriptSrc: ['scripts.com'],
...
}));[/code]
These can all be enabled in an express app using some combination of helmet and lusca modules
Each header is further described here: Seven Web Server HTTP Headers that Improve Web Application Security for Free
Give the following GET request:
[code]// GET /search?firstname=John&firstname=John[/code]
What will this return?
[code]req.query.firstname[/code]
It will return the following:
[code][“John”, “John”][/code]
Express populates HTTP request parameters with same name in an array
An attacker can:
Solution:
Evil regex can take exponential execution time when applied to certain non-matching inputs.
By default, regex gets executed in event loop thread, so could be exploited for DoS attack.
In order for a regex to be evil regex, several requirements should happen:
( )+
( a+ )+
( a|aa )+
1. Grouping with repetition, and
2. Inside repeated group, repetition or alternation with overlapping.
Solution:
Final Notes:
This a very cool project that has sprung up semi-recently that is working towards making the nodejs ecosystem more secure
That's all for now folks.
301 Moodie Dr. Unit 108
Ottawa ON K2H 9C4