A recent study conducted by Snyk on the state of open-source security has turned up alarming results—for NPM packages, 86% of security vulnerabilities reside in secondary dependencies that you often have little control over.

What Are Secondary Dependencies?

When you install something from NPM, you aren’t just installing one package, you’re installing that package, plus any of its required dependencies as well. You can view this dependency tree for your own projects with npm ls –depth=10. Even a basic project with two packages installed actually contains four levels of dependencies totaling 10 actual packages:

The problem, then, is obvious. You’re pulling code from many more packages than your package.json would suggest. And, each one of those packages is a potential security bug.

According to the report from Snyk, this is exactly what happens in open-source environments like NPM and Ruby Gems. The problem is rampant, and most bugs come from indirect packages that you didn’t install manually.

The bright side: this problem isn’t as bad as it sounds. NPM has a built-in tool for auditing that will catch most of the nasty ones and tell you to update. Because of the prevalence of auditing, these security bugs are getting more attention and are getting fixed when they arise, with updates pushed out quickly to the affected users.

The majority of the bugs found by Snyk were potential XSS attacks, and while that’s not great, their real-world impact is fairly low. The main impactful bugs came down to a few dozen prototype pollution attacks—potential arbitrary code execution—as well as some malicious or hacked packages designed specifically to try and sneak their way into unsuspecting package.json‘s.

The problem is also getting better, or at least getting more attention. The number of bugs reported in NPM was down 20% over last year, and the same trend applied to other package manager ecosystems.

The main takeaway from all this: you should think about where your code comes from. With the rise of FOSS software, it’s easy to get caught up in dependency hell with code you didn’t plan on adding.

The Solution: Auditing

There are bound to be bugs in random pieces of open-source code, and while you can’t really fix some of the small ones without developing everything in-house, you can catch some of the particularly nasty ones with regular audits.

The problem isn’t particularly new though, and npm has a built in tool for this—npm audit. You definitely have seen it before, because it runs automatically whenever you install:

NPM’s built-in auditing mostly just checks for updates to packages that fix certain bugs, so there’s always an upgrade you can make (though potentially breaking) that can fix the problem. Other security scanners do exist though, like Snyk themselves, who run a service for checking GitHub projects, and maintain a publicly accessible database of known bugs that you can check out.