Securing Node.js Applications

Increasingly Node.js is being used by more and more people. Many companies web app backend is written in Node.js for either their Websites, API, etc. Also, Javascript is being seen as a universal language nowadays since it can be used to develop the frontend of the websites (using frameworks like react.js, angular, vue.js), native apps – ios and android (using react native, ionic, Native script), for VR apps (using react VR). Some people are also using js for machine learning, neural networks (Brain.js) but still, its a long road to go in that domain. Now the backend of your apps can be built using Node.js and is very suitable for development of APIs and microservices.

Given said that, many developers and companies would prefer Javascript and related frameworks and Node.js since multiple works get done using one language only. Now let us talk about making your Node.js backend secure. I will quickly walk you through the key steps you require to do that without having much expertise in cybersecurity.

1. Use HelmetJS

Use this to quickly set up headers so that the browsers can use their inbuilt functionality to protect your app.

Install it using > npm install helmet

Then in an express app, add the following

        const express = require('express') 
        const helmet = require('helmet') 
        const app = express()
    


then to use helmet’s functionality use the following. hidePoweredBy is to confuse the person trying to understand what language your website is written in. For other headers read the official documentation.

        app.use(helmet({
            hidePoweredBy: { setTo: 'Python-59' },
            frameguard: {action: 'deny'},
            xssFilter: true,
            noSniff: true, 
            ieNoOpen: true, 
            hsts: {maxAge: ninetyDaysInMilliseconds},
            dnsPrefetchControl: false,
        }));
    

The app.use(helmet(...)) can be used to include all the functionalities except, the noCache() and contentSecurityPolicy() which can be implemented as follows. Refer the HelmetJS documentation to setup content security policy as per your need and set up other headers. =>

        app.use(helmet.contentSecurityPolicy({
            directives: {
                defaultSrc: ["'self'"],
                scriptSrc: ["'self'", "trusted-cdn.com"]
            }
        }));

        app.use(helmet.noCache());
    

2. Joi

Joi helps to validate user input in your web app or API. It can be easily installed by using –

npm install joi

Now, Joi can be used in a file as following –

        const Joi = require('joi');

        Version = req.params.Version.toString();
        console.log(Version);
        const versionSchema = {
            a: Joi.string().alphanum().length(2)
        };
        const {error, value} = Joi.validate({ a: Version }, versionSchema);
        if (error !== null) {
            res.send('NOTOK');
        } else {
            // write your code here which runs after validation is success. 
        }
    

In the above code, “Version“ is the incoming value we need to validate against our desired schema (versionSchema). As an example, version schema requires the “Version” to be a string, an alphanumeric with a length of 2. If the variable violates this schema, an error is thrown else it passes to the else statement where the proceeding code can be written.

3. Dependencies check using Snyk

Many times, websites or apps are left vulnerable since the libraries or packages they use get deprecated or are vulnerable themselves. Now, since the maker of those packages will push a new version on the npm but the versions of those packages in your project are still vulnerable and old.

Hence, it is very important to update your packages to stable versions timely. Sometimes, the packages are completely leftover or are deprecated in which case they need to be replaced or removed.

Snyk is a very important tool that comes into use in such scenarios. It’s easy and free to use and gives us a proper report about our dependencies in the project. It also informs us if there is a new vulnerability identified.

Now let’s discuss how to use this,

Install snyk tool
Run the following command from a terminal, snyk should be installed globally and need not be installed for every project you work on. npm install -g snyk

Authenticate your machinesnyk auth

Navigate into your code’s directory and run:snyk monitor

To resolvesnyk wizard

To apply snyk patchesnpm run snyk-protect

4. CORS – for protecting your APIs

CORS which refers to Cross-Origin Resource Sharing is a mechanism that uses HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin (as per dev Moz docs).

Hence if you want your APIs (which run on a different origin) to run on a specified domain http://yourwebsite.com, then you have to allow your website domain from within the API as follows –

Send response from your API as follows –

        response = {
            statusCode: 200,
            headers: {
                "Access-Control-Allow-Origin" :  http://yourwebsite.com
            },
            body: JSON.stringify(“Output Response is this.”),
            };
    

Note that, since CORS is an HTTP header so, this is only for the security of the user and can be overwritten by any user by disabling CORS on their browser. You can set Access-Control-Allow-Origin = “*” so that your API runs on the global origin.

But it helps, in case, if an unauthorized developer tricks a user on his website http://evil-website.com by fetching the data from your API if your API key is compromised, the data won’t display on the user’s website and will show CORS error on the console until user himself turns the cors off on their browser.

5. OWASP top 10

The OWASP Top 10 is a powerful awareness document for web application security. It represents a broad consensus about the most critical security risks to web applications. Check it at (https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project). Now I highly recommend going through the OWASP Node goat project for securing the Node.js applications which cover the following topics –

  1. Injection
  2. Broken Authentication
  3. Cross-Site-Scripting (XSS)
  4. Insecure Direct Object Reference
  5. Security Misconfiguration
  6. Sensitive Data Exposure
  7. Missing Function Level Access Control
  8. Cross-Site Request Forgery (CSRF)
  9. Using components with known vulnerabilities
  10. Redirects

There is a good explanantion on each of this topic on the node goat project at http://nodegoat.herokuapp.com/tutorial

6. 12 Factor APP

If you are building a SAAS, you may need to check the 12 factor app here at https://12factor.net/. It will help you structure your application from the dawn. As per the 12 factor app, securing your config details, separating dev-prod stages, having logs at the appropriate locations, etc. are very important for a secure app.

Conclusion

I believe security is not something that you want to think in the last week before making your application public. Rather, the security practices need to be taken care of from the start and we need to review it at regular intervals in our software development cycle.

Leave a Reply

Your email address will not be published. Required fields are marked *