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 HTTP 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]
Deploying Node.js application to a PaaS
Monitoring and operating 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.
"Fact: Security is a part of your job as a Node.js developer." via @RisingStack #nodejs #security
Click To Tweet
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.
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.
"Always log errors, but never show them to users." via @RisingStack #nodejs #security
Click To Tweet
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
In Node.js it is easy to set these using the Helmet module:
Helmet is available for Koa as well: koa-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.
(The example is taken from the cookie-session module documentation.)
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!
"Always look for vulnerabilities in your #nodejs modules. You are what you require." via @RisingStack #security
Click To Tweet
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:
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.
Next up
Node.js security is not a big deal after all is it? I hope you found these rules to be helpful for securing your Node.js applications - and will follow them in the future since security is a part of your job!
If you’d like to read more on Node.js security, I can recommend these articles to start with:
Node.js Security Tips
OWASP’s Top Ten Cheat Sheet
Node.js security checklist
In the next chapter of Node Hero, you are going to learn how to deploy your secured Node.js application, so people can actually start using it!
If you have any questions or recommendations for this topic, write them in the comments section.
(twitter card photo credit: www.perspecsys.com)