Dependencies
With Node.js, advent came npm - Node Package Manager and more recently yarn by Facebook. Both promote reusable JavaScript code, going beyond Node.js's scope - following the best practices and with tools such as Browserify, now developers write code once and can use it both server and client side.
Together with other tools and services like the popular Mocha test framework or Github free repositories for Open Source projects and it's integration with Travis CI, there was an important overall increase on code quality.
This is the perfect match with OWASP SCP recommendation "_use tested and approved managed code rather than creating new unmanaged code for common tasks".
Nevertheless, while writing their own applications, developers should handle third-party dependencies carefully as they will be part of their applications.
We will focus on npm as it is still the most used package manager. In general yarn is full compatible with npm which doesn't mean that discussed issues also apply to it. In fact, yarn came to solve some of the issues.
To install a dependency using npm we do:
$ npm install [PACKAGE-NAME] --save
Then PACKAGE-NAME
is downloaded and stored locally at node_modules
folder
and the package.json
file is updated to track the new dependency.
By default, issuing the npm install command as we did above downloads the
most recent PACKAGE-NAME
version and package.json
is updated with an entry
like "package-name": "^1.2.4"
in the dependencies
section.
Assuming you're using a version control system like Git, node_modules
is
something you exclude. So, whenever you checkout your application from Git, you
have to install its dependencies; what you're running:
$ npm install
And here is the problem.
Right now you're not sure that you got the package-name
version 1.2.4
.
Perhaps in the meantime, package-name
received some fixes and the actual
version is could be 1.2.10
. Or some features were improved or new ones added
and now it is at version 1.3.0
.
- What if these changes done to
package-name
break your application? - What if these changes introduces security vulnerabilities?
Let's answer these questions, starting with the second one.
You should always audit your dependencies. As they will be part of your application, it is your responsibility to do it. More, it is your duty.
Some developers rely on Github stars to assess package's "quality". However if you think about Github stars as Facebook likes, we can all agree that they don't mean much.
Hopefully your task won't be a hard one. There are plenty of interesting projects assessing npm packages security. You have, for example, Snyk and the snyk npm package which will help you find, fix and monitor known vulnerabilities. This is a tool that you can easily integrate into your CI (Continuous Integration) pipeline or run it as a package.json script (as you probably run linter and tests).
Node Security Platform and its nsp tools is another option. Both will mitigate the risk of using insecure dependencies.
To shed light on how to prevent insecure dependencies from reaching your repository, remember that also Git (and most of the version control systems) provides hooks. Git, for example, has a pre-commit hook which can be used to run snyk or nps (or both, why not?), aborting in case of failure.
It's time to answer the first question - "What if these changes done to
package-name
break your application?".
Well, npm shrinkwrap answers the question with "locking down dependency versions for publication".
After running all of your tests and security assessment, it is time to run:
$ npm shrinkwrap
If you don't have one, a npm-shrinkwrap.json
file will be created from the
package.json
one with something like:
{
"name": "my-app",
"version": "1.0.0",
"dependencies": {
"package-name": {
"version": "1.2.4",
"from": "package-name@latest",
"resolved": "https://registry.npmjs.org/sax/-/package-name-1.2.4.tgz"
}
}
}
When running npm install
to install your application dependencies,
npm-shrinkwrap
will take precedence despite the fact that package-name
may
have been updated.
A final and important note about "typo-squatting" attacks - With a huge database of packages are identified by their names, attackers have been publishing malicious packages using names similar to some popular packages.
Watch what you type and always validate that you have what you're looking for from your package manager.