It’s no secret that JavaScript is one of today’s leading programming languages, used extensively in website and mobile application development. It’s particularly popular because when combined with Node.js, JavaScript can be used to produce interactive web content, enabling games and communication applications to run directly in the browser for the user, installation-free.

Unfortunately, JavaScript is also used to code pop-up ads and other content that can be malicious. This, combined with its popularity and the richness of its open source ecosystem, also means the likelihood of an attack is increased for programs written in JavaScript. To overcome the biggest challenges, you first need to understand the different moving parts.

Download the Report: The 2021 State of Open Source Vulnerabilities

About the JavaScript Ecosystem

As mentioned, the JavaScript ecosystem is incredibly extensive, including several different package manager, framework, and library options that developers can leverage to enrich their programs with little effort.

In 2019 alone, npm (Node Package Manager), the most popular of the JavaScript package managers, grew rapidly. npm now reports being “the largest software registry in the world,” exceeding 1,300,000 packages. Having been acquired by GitHub (Microsoft) not long ago, we can only expect npm’s size to continue increasing.

Add to that the increasing availability and use of Angular, React, Vue, and other frameworks, and it’s no wonder that JavaScript is so popular.

Fortunately, JavaScript applications are actually not the most vulnerable options out there; in fact, JavaScript is actually one of the safer routes you can take, as reported in DarkReading in March 2020. Given that, and since JavaScript is so important and useful, the best way to protect your application (and your users) is to be aware of the dangers and to take the necessary precautions as early in development as possible.

Know Your Vulnerabilities

The biggest step to take in protecting your applications is mitigation, which starts with knowing what vulnerabilities you have in your app. The best way to do this is to understand the libraries you’re using, to keep your dependencies updated, and to regularly track advisories.

It’s important to make sure the libraries you’re using are regularly maintained and kept current. This can be a challenge, though, when you consider how libraries are typically built. Like legos, open source libraries are, more often than not, built on top of other libraries, which are composed of other libraries, and so on and so forth. Frequently, vulnerabilities actually come from these indirect dependencies, since the deeper you go, the harder it is to track and the harder it is to know if the indirect dependencies are maintained. But, by choosing up-to-date libraries for your app, you’ve already taken a step in the right direction.

You need to make sure you keep those dependencies as updated in your app as they are in their package managers. Make sure you regularly upgrade your packages (especially if the upgrade guarantees no breaks) and do this especially when there are notifications about hot-fixes and patches that handle vulnerabilities. This is where an open source vulnerability management solution like FOSSA can be of particular assistance.

Finally, don’t rely only on the package managers for a healthy app. Make sure you stay on top of the advisories as well. Use and learn from Open Web Application Security Project® (OWASP), CWE, National Vulnerability Database (NVD), and other sources to stay on top of the biggest threats, and be aware of bulletins issued by the vendors whose products you’re using. Node.js, for example, offers an extensive bulletin notifying of their vulnerabilities and available fixes.

Most important is to remember: The more proactive you are, the safer your apps are.

Prioritize Your Vulnerabilities

Vulnerabilities exist everywhere, to such an extent that dealing with them can feel overwhelming. It’s very difficult — and in some cases nearly impossible — to address every single one of them, which is why it’s so important to prioritize. To help do this, you can use the Common Vulnerability Scoring System (CVSS) scoring system. Fix the vulnerabilities based on their severity, choosing the most risky first. CWE also offers some great guidance on what it really means to prioritize; you can use CWE to help prioritize vulnerabilities that may affect your specific environment.

Additionally, leverage built-in features offered by the tools you’re using. For example, npm offers `npm audit` built into its CLI. Unfortunately, one of the complaints in the field is that more often than not, the false positives add an extra component of confusion and an extra layer of work. For more robust comprehensive protection and far fewer false positives, software composition analysis tools like FOSSA offer security scanning for your repositories, including every time you open a pull request.

Finally, it’s important to note that these are just a few of the methods recommended for prioritizing. Other factors include whether the vulnerable code is accessible during production, whether the exploit is known, the amount of damage that can be done by the exploit, and more. Take a look at the CVSS system to learn a bit more about leading factors that help determine the relative danger of any given vulnerability.

Leading JavaScript-Related Vulnerabilities

Since prioritization is so key to staying secure, you should know which types of vulnerabilities most commonly affect your JavaScript projects. OWASP shows that three of their top-10 types are related to JavaScript in different ways: Cross-site scripting (XSS), insecure deserialization, and use of components with known vulnerabilities (apropos indirect dependencies). The latter is so critical, in fact, that OWASP now maintains Retire.js, which is a library designed specifically to track JS-related vulnerabilities and to offer relevant remediation. Similarly, XSS is one of the most common repeat-appearers on the annual list.

The XSS vulnerability can lead to massive damage. In January 2019, for example, an XSS vulnerability was disclosed in the Steam chat service, which could have led to millions of users being exposed to its dangers; another XSS vulnerability was also found in Steam in 2017, which could have affected their entire user base (over 120 million).

The core lesson here: Prioritize your vulnerabilities, and start by fixing those that are most common and easiest to access within your environment.

The Most Vulnerable JavaScript Libraries

No less important than being aware of the most dangerous vulnerabilities is being aware of the most vulnerable packages. Putting these two factors together becomes a very powerful defense against attacks on your app.

Updating packages at will can be quite problematic and lead to major and expensive breaks in your build — which is why it may not always make sense to fix every vulnerability. Instead, combine what you know about the most dangerous vulnerabilities (to your app specifically) with the packages that you use to decide how and where to start fixing things and improving your security posture. Continue weighing pros and cons of risks when deciding. And document decisions you’ve made as you go so that you can track the policy you’ve curated for your organization specifically.

`lodash` and `jquery` are notoriously stricken with vulnerabilities. A quick search on NVD shows seven recent medium-, high-, and critical-severity vulnerabilities uncovered in lodash, and 13 for jquery in the last year alone. If you’re using those packages, you should stay on top of things and follow related alerts. It's worth understanding how these vulnerabilities affect your code health; also, it's important to stay on top of things here and fix affected components every time updates are offered. In fact, these are also two good examples of when it might be best to break a build to update or use alternative packages.

Recommendations for JavaScript Security

The bottom line for addressing security vulnerabilities in JavaScript is that you need to keep tabs on what you’re “feeding” your code to ensure the app comes out healthy. Doing this isn’t always easy, but by following a couple of best practices, you’ll be that much closer to success:

  • Use maintained versions of well-known, common packages
  • Fix the packages with the vulnerabilities most dangerous to your environment first
  • Check packages before using to ensure they are well-maintained and up-to-date
  • Be aware of your dependencies’ dependencies
  • Align with your company policies for security and compliance

By using a code scanning tool, this kind of project becomes exponentially easier. FOSSA Security Management integrates with your repository to scan your code and alert you with vulnerability data.