Dependency audits on JavaScript projects
At Ad Hoc, many of our projects use modern JavaScript. On the backend, we have projects using Node.js, and on the frontend we use libraries like React.
Like most JavaScript applications, our projects rely on open source npm packages. In the last year, our teams noticed an increase in news articles about npm security vulnerabilities. Stories like:
- Compromised JavaScript Package Caught Stealing npm Credentials
- Malicious code found in npm package event-stream downloaded 8 million times in the past 2.5 months
- npm Pulls Malicious Package that Stole Login Passwords
Ensuring our applications are secure is a critical part of our work. Ad Hoc supports a number of high visibility, high traffic government websites including HealthCare.gov and VA.gov. Security vulnerabilities pose a serious risk to both the integrity of federal websites and the smooth operation of the services these sites enable.
To help improve the security of our projects, we integrated a way to audit our application dependencies into our agile development process. The goal was to ensure we shipped code with no malicious code and kept our packages up-to-date.
The QPP Process
The Dependency Audit Process was originally created by Ad Hoc’s Quality Payment Program (QPP) team for our work on the project with the Centers for Medicare & Medicaid Services. During each of QPP’s 2-week sprints, we conduct an audit of every dependency in our project.
We check for vulnerabilities with npm audit
, which ships with npm and can help identify packages with vulnerabilities, and npm outdated
to identify outdated packages. We also use tools like Snyk which monitors our repository for vulnerabilities and notifies us when there is trouble. Sonarcloud is another tool that monitors for vulnerabilities and provide us with useful analytics like code coverage, code quality, and potential bugs.
Whenever we find a vulnerability or outdated package, we apply patches and updates, test them, and merge them into our projects. Pretty simple!
Results
Since we’ve introduced dependency audits, we’ve noticed a few things. We have a clear audit trail of when packages are upgraded. Because we update our packages regularly, dependency audits take less than an hour to complete. Also, upgrades to our packages are a lot easier to do. We also noticed we’re less likely to encounter security vulnerabilities that require hotfixes.
This is a fairly simple and straightforward process, but the real benefits come from baking it into our routine sprint work. Keeping applications secure requires constant work, and without a defined process it’s easy for that work to slip off the to-do list. By making it routine, we strengthen the security of our project, help the government better deliver critical services, and greatly improve the developer experience.