7 Steps to Secure JavaScript in 2021

These practices will help to secure your JavaScript execution

Viduni Wickramarachchi
Bits and Pieces

--

JavaScript is used everywhere today. It runs in your browser as well as in your backend. Besides, JavaScript is a highly dependent ecosystem on third-party libraries. Therefore, securing JavaScript requires following best practices to reduce the attack surface.

But, how do we keep JavaScript applications secure? Let’s find out.

1. JavaScript Integrity Checks

As a frontend developer, you may have used <script> tags to import third-party libraries. Have you thought about the security risks of doing so?

What if the third-party resource has been tampered with?

Yes, these are things that can happen when you render external resources on your site. As a result, your site may face a security vulnerability.

As a safety measure for this, you can add an integrity (also known as Subresource integrity — SRI) code to your script as follows.

<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous">
</script>

The integrity attribute allows a browser to check the fetched script to ensure that the code is never loaded if the source has been manipulated.

Note: Still, you have to ensure that the code you refer initially doesn’t contain any vulnerabilities.

2. Frequent Tests for NPM Vulnerabilities

I hope all of you know that we can use npm audit command to detect vulnerabilities for all installed dependencies. It provides vulnerability reports and provides fixes for them. But how often do you do that?

Unless we automate it, these vulnerabilities will stack up, making it difficult to fix them. Remember, some of them could even be critical, allowing severe exploits.

As a solution, you can run NPM in your CI for each pull request to identify vulnerabilities. Therefore, you can prevent any vulnerabilities from going unnoticed.

NPM audit security report example

However, there are some vulnerabilities that will require a developer’s manual intervention to be solved.

An extra mile from GitHub

Lately, GitHub introduced a bot name Dependabot, to scan the NPM dependencies automatically and notify you by email stating the risks.

One such email I have gotten for one of my projects

Besides, suppose you enabled the “automated security fix PRs” option. In that case, GitHub will send an automated PR to fix these issues, addressing the security risks in advance.

Build with independent components, for speed and scale

Instead of building monolithic apps, build independent components first and compose them into features and applications. It makes development faster and helps teams build more consistent and scalable applications.

OSS Tools like Bit offer a great developer experience for building independent components and composing applications. Many teams start by building their Design Systems or Micro Frontends, through independent components.
Give it a try →

An independently source-controlled and shared “card” component. On the right => its dependency graph, auto-generated by Bit.

3. Keep Minor and Patch Version Updates Enabled

Have you ever seen ^ or ~ symbol in front of any NPM package version? These symbols indicate the automatic version bump for minor and patch versions (depending on the symbol).

Technically, minor and patch versions are both backward compatible, reducing the risk of introducing bugs to the application.

Since most third-party libraries release hot-fixes vulnerabilities as patch version bumps, at least enabling automated patch updates helps to reduce security risks.

4. Have Validations in Place to Avoid Injections

As a rule of thumb, we should never rely only on client-side validations since attackers can change them as required. However, some JavaScript injections can be omitted by having validations for every input.

For Example, if you type in the comment field anything with quotes <script><script/>, those quotes will be replaced with double — <<script>><</script>>. Then the entered JavaScript code will not be executed. This is called Cross-Site Scripting (XSS).

Likewise, there are a few other common ways to conduct JavaScript injection.

  1. Use the developer’s console to insert or change the JavaScript.
  2. Entering “javascript:SCRIPT” into the address bar.

Preventing JS injections is important to keep your application secure. Like I mentioned before, having validations place is one method to prevent it. For example, before saving any input to the database, replace all < with &lt;, and all > with &gt; .

Content Security Policies (CSP) are another way to avoid malicious injections. Using CSP is quite straightforward as follows.

Content-Security-Policy: trusted-types;
Content-Security-Policy: trusted-types 'none';
Content-Security-Policy: trusted-types <policyName>;
Content-Security-Policy: trusted-types <policyName> <policyName> 'allow-duplicates';

For more information about CSPs refer to these guidelines.

5. Always Keep Strict Mode On

Having Strict mode on will limit you from writing unsafe code. Besides, its straightforward to enable this mode. It’s as simple as adding the below line as the first in your JavaScript files.

use strict

When the strict mode is on;

  • It throws errors for some errors that were previously kept silent.
  • Fixes mistakes that make it difficult for JavaScript engines to perform optimizations.
  • Prohibits the use of reserved words likely to be defined in future versions of ECMAScript.
  • Throws errors when ‘unsafe’ actions are taken (such as gaining access to the global object).

Every modern browser has supported strict mode for years. If the browser does not support strict mode, the expression is simply ignored.

6. Lint Your Code

Linters perform static analysis on your codebase. It helps to establish quality and avoid common pitfalls. Since quality goes hand in hand with security, Linting helps to reduce the security risks. Few popular tools that we use for JavaScript as follows.

  • JSLint
  • JSHint
  • ESLint

Further, tools like SonarCloud can also be used to identify code smells and known security vulnerabilities. A Sonar report would look like the following.

Source

Note: As you can see in the above image, it has a section for security, that shows vulnerabilities, security hotspots.

7. Minify & Uglify Your Code

Attackers will most often try to understand your code to hack their way through. Therefore, having a readable source code in the production build increases the attack surface.

As a common practice, if you minify and ugly your JavaScript code, it is difficult to exploit vulnerabilities in the code you have written.

However, if you want extreme measures to hide your code from users/clients, it should be kept on the server-side without sending it to the browser at all.

Summary

Focusing on security is very important, especially in JavaScript applications, to make your application secure. With minimal tools, you can secure JavaScript to prevent common attacks.

Besides, suppose you look for advanced solutions. In that case, there are tools like Snyk, WhiteSource which are specialized to scan the vulnerabilities in your code and automate it with continuous integrations.

Furthermore, if you follow any other practices, please do mention them in the comments below. Thanks for reading!

--

--