This article is the 11th part of the tutorial series called Node Hero - in these chapters, you can learn how to get started with Node.js and deliver software products using it.
In this Node.js security tutorial, you are going to learn how to defend your applications against the most common attack vectors.
Upcoming and past chapters:
- Getting started with Node.js
- Using NPM
- Understanding async programming
- Your first Node.js server
- Node.js database tutorial
- Node.js request module tutorial
- Node.js project structure tutorial
- Node.js authentication using Passport.js
- Node.js unit testing tutorial
- Debugging Node.js applications
- Node.js Security Tutorial [you are reading it now]
- How to Deploy Node.js Applications
- Monitoring Node.js Applications
Node.js Security threats
Nowadays we see almost every week some serious security breaches, like in the LinkedIn or MySpace cases. During these attacks, a huge amount of user data was leaked - as well as corporate reputations damaged.
Studies also show that security related bug tickets are open for an average of 18 months in some industries.
We have to fix this attitude. If you develop software, security is a part of your job.
Start the Node.js Security Tutorial
Let's get started, and secure our Node.js application by proper coding, tooling, and operation!
Secure Coding Style
Rule 1: Don't use eval
Eval can open up your application for code injection attacks. Try not to use it, but if you have to, never inject unvalidated user input into
eval
.
Eval is not the only one you should avoid - in the background each one of the following expressions uses eval:
setInterval(String, 2)
setTimeout(String, 2)
new Function(String)
Rule 2: Always use strict mode
With
'use strict'
you can opt in to use a restricted "variant" of JavaScript. It eliminates some silent errors and will throw them all the time.'use strict'
delete Object.prototype
// TypeError
var obj = {
a: 1,
a: 2
}
// syntax error
Rule 3: Handle errors carefully
During different error scenarios, your application may leak sensitive details about the underlying infrastructure, like:
X-Powered-By:Express
.
Stack traces are not treated as vulnerabilities by themselves, but they often reveal information that can be interesting to an attacker. Providing debugging information as a result of operations that generate errors is considered a bad practice. You should always log them, but never show them to the users.
Rule 4: Do a static analysis of your codebase
Static analysis of your application's codebase can catch a lot of errors. For that we suggest using ESLint with the Standard code style.
Running Your Services in Production Securely
Using proper code style is not enough to efficiently secure Node.js applications - you should also be careful about how you run your services in production.
Rule 5: Don't run your processes with superuser rights
Sadly, we see this a lot: developers are running their Node.js application with superuser rights, as they want it to listen on port 80 or 443.
This is just wrong. In the case of an error/bug, your process can bring down the entire system, as it has credentials to do anything.
Instead of this, what you can do is to set up an HTTP server/proxy to forward the requests. This can be nginx or Apache. Check out our article on Operating Node.js in Production to learn more.
Rule 6: Set up the obligatory HTTP headers
There are some security-related HTTP headers that your site should set. These headers are:
- Strict-Transport-Security enforces secure (HTTP over SSL/TLS) connections to the server
- X-Frame-Options provides clickjacking protection
- X-XSS-Protection enables the Cross-site scripting (XSS) filter built into most recent web browsers
- X-Content-Type-Options prevents browsers from MIME-sniffing a response away from the declared content-type
- Content-Security-Policy prevents a wide range of attacks, including Cross-site scripting and other cross-site injections
var express = require('express')
var helmet = require('helmet')
var app = express()
app.use(helmet())
Rule 7: Do proper session management
The following list of flags should be set for each cookie:
- secure - this attribute tells the browser to only send the cookie if the request is being sent over HTTPS.
- HttpOnly - this attribute is used to help prevent attacks such as cross-site scripting since it does not allow the cookie to be accessed via JavaScript.
Rule 8: Set cookie scope
- domain - this attribute is used to compare against the domain of the server in which the URL is being requested. If the domain matches or if it is a sub-domain, then the path attribute will be checked next.
- path - in addition to the domain, the URL path that the cookie is valid for can be specified. If the domain and path match, then the cookie will be sent in the request.
- expires - this attribute is used to set persistent cookies since the cookie does not expire until the set date is exceeded.
In Node.js you can easily create this cookie using the cookies package. Again, this is quite low
-level, so you will probably end up using a wrapper, like the cookie-session.
-level, so you will probably end up using a wrapper, like the cookie-session.
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.use(cookieSession({
name: 'session',
keys: [
process.env.COOKIE_KEY1,
process.env.COOKIE_KEY2
]
}))
app.use(function (req, res, next) {
var n = req.session.views || 0
req.session.views = n++
res.end(n + ' views')
})
app.listen(3000)
Tools to Use
Congrats, you’re almost there! If you followed this tutorial and did the previous steps thoroughly, you have just one area left to cover regarding Node.js security. Let’s dive into using the proper tools to look for module vulnerabilities!
Rule 9: Look for vulnerabilities with Retire.js
The goal of Retire.js is to help you detect the use of module versions with known vulnerabilities.
Simply install with:
npm install -g retire
After that, running it with the retire command will look for vulnerabilities in your
node_modules
directory. (Also note, that retire.js works not only with node modules but with front end libraries as well.)Rule 10: Audit your modules with the Node Security Platform CLI
nsp
is the main command line interface to the Node Security Platform. It allows for auditing a package.json
or npm-shrinkwrap.json
file against the NSP API to check for vulnerable modules.npm install nsp --global
# From inside your project directory
nsp check
No comments:
Post a Comment