How To Secure Your JavaScript Backend via Node.js and Express.js

JavaScript as a backend through Node.js and Express.js

JavaScript is a strange little big language. For a long time, it wasn’t considered a ‘real’ programming language because of the way JavaScript works under the hood. It is just a scripting language after all. This means no compilation is required, needs another program in order to run, and can exist as small snippets of code nested inside other applications.

JavaScript has grown up since its heyday of kitschy 90s browser snowflake effects. Since the early 2000s, JavaScript has successfully taken over the frontend, backend, and even parts of native mobile application development.

But is it secure?

Frontend web runs on JavaScript. With the release of Node.js in 2009, JavaScript backend development has grown into a fully supported suite of tools, SDKs, frameworks, libraries, and massive developer communities. It is supported by cloud providers like Google, Microsoft, and Amazon through services like cloud functions, lambdas, and server instances. It is used by major sites like Netflix, PayPal, and Walmart.

So when we ask the question — how secure is JavaScript as a backend? What we’re really asking is how secure is Node.js?

What Is Node.js and How It Works

In a nutshell, Node.js is a cross-platform JavaScript-based runtime environment for servers and applications. The runtime is the space where code gets executed. It sits on your cloud-based machine instance, or whatever setup that supports Node.js such as cloud functions. Node.js interacts with the hardware of the machine in order to execute your program.

This program is often implemented through a series of third-party libraries and frameworks that allow us to define and execute our database connections, processes, authentication, user sessions, and anything else that we may want our application to do.

While Node.js itself has its own set of security vulnerabilities such as NPM phishing and regular expression Denial of Service attacks, the real threat actually lies in the jigsaw way your application gets built.

For example, Express.js is often used to provide server-side logic. It is a backend framework that is used by developers to create APIs for frontend consumption. Potential security vulnerabilities can arise when APIs are not secured during the delivery process.

One way to prevent this is to implement TLS (Transport Layer Security) and encryption to deter common and easy hacks such as packet sniffing and man-in-the-middle attacks. The TLS ensures that the connection between client and server is always secure, and it is the next progression from SSL (Secure Socket Layer) encryption.

Securing Your Express.js in code

One way to enforce security on your data, server, and code is to use HTTPS. By default, Node.js sends content over HTTP. Using the HTTPS module, you can force communication to be done over a secure channel with the client. Here is an example of how you can implement it:

To create a certificate required by TLS, you can do so using a tool called Certbot. The installation process may be different, depending on what the server is running on. For an Nginx installation on Ubuntu 16.04 (xenial), you’ll need to install snapd. snapd is a dependency bundling program.

To do this, open up the command line and run the following:

This will install the latest version of snapd.

The next step is to remove any certbot-auto and Certbot OS packages to prevent conflicts from occurring. Depending on your OS package manager, the exact command to do this can range. Here are a few examples:

Once any preloaded installation is removed, you can install the certbot version that gives you more control over the certificate generation. Here is the command for it:

Now it’s time to set the certbot command so that it will run.

There are two ways you can run certbot. The first is to get a certificate and have certbot deal with your Nginx configuration.

Or if you just want to get the certificate and do your own Nginx configuration, run this command instead:

Every certificate generated and installed by certbot has an expiration time and date. To check the automatic renewal, use the following command:

The last step to this is to confirm that certbot worked by navigating to the https:// domain in your browser or via postman API call.

Increase Your Encoding Scope

While HTTPS and transporting your data over a secure connection helps, it is not the only technique that can be used to create digital armor for your Node.js application.

You can use escape-html to encode the HTML content you receive. This automatically escape strings and prevents cross-site scripting.

To install escape-html into your project, use the following command:

To use in your Node.js project:

If you’re using Node.js as part of a MEAN or MERN stack, it’s also good practice to escape any CSS that you may receive. While CSS itself may seem harmless, it is another space where special characters can find their way into your backend.

An easy way to do this is to use the web API CSS.escape() functionality inside your JavaScript code. Here is an example of the syntax:

With HTML and CSS encoding covered, it also makes sense to include JavaScript encoding to complete the basic web stack.

One good Node.js module is js-string-escape. Here is how you can install it:

Here is an example of how to use it:

Helmet and Session Cookies

When it comes to security, Helmet is a Node.js package that contains 11 security modules that you can use to ensure that your JavaScript backend remains robust against vulnerabilities.

Here is a basic installation and usage of Helmet with express.js:

By default, Express has default cookie settings that helps you get started quickly in your development process. However, anything that remains in its default state will always pose a security risk. Why? Because the knowledge and information concerning its settings and potential ways to hijack it is available on the Internet.

The quick and easy way to prevent this is to manually configure your session cookies by doing the following:

  • set your secret and salt it
  • give your application a new key
  • flag your app for httpOnly to prevent hijacks from non http sources
  • set secure to true to force acceptance from TLS/SSL requests only
  • set the domain to where the cookie is expected to come from
  • set the path from where it is acceptable from the application’s domain
  • and finally, when the cookie expires.

Here is the code sample of how to configure your cookie in Express.js:

Conclusion

This brings us back to our original question: does using JavaScript as your backend make your application more prone to security risks?

The answer to this is no.

Like other backend programming languages such as Java and C++, we still need to install a series of security layers to prevent hijacks and data leaks from occurring.

The major vulnerabilities do not lie in Node.js or Express.js — but rather how it gets implemented. It doesn’t matter what language or backend framework you end up using, if defaults are left as defaults, you are inviting malicious users to your data.

Node.js has the capabilities to secure your application on multiple levels, making it a good choice where security is concerned.

Aphinya Dechalert

Aphinya Dechalert / About Author

Aphinya is a skilled technical writer with field experiences in software development, agile, and JavaScript full stack with AWS and Google cloud. She is a developer advocate and community builder, helping others navigate their journeys and careers as developers.