Ask HN: How do you security-audit external software using NPM packages?
106 points| BjornW | 4 years ago
At my current client I've been doing more and more security related tasks such as audits on external software. Currently the type of software I audit are WordPress plugins. I have more than 15yrs of experience with WordPress and in the past I could fairly easily assess a WordPress plugin's potential security impact(s). Nowadays not so much due to the seemingly increased usage of npm packages included with these plugins.
Often these plugins do not include a package.json, package-lock.json nor are the javascript files readable (bundled & minified). This makes using npm audit near impossible. Good for production, less for audits.
Sometimes I can grab development files such as package.json, package-lock.json from a public repo, but in the case of so-called 'premium' plugins a public repo is usually absent.
So my question is: How do you (security) audit external software depending on npm packages?
jhugo|4 years ago
If you accept receiving and using plugins that contain unauditable blobs of software, whether it's minified JS or a binary, a good-quality audit is going to be virtually impossible.
In many other ecosystems this wouldn't be normal. If a Rust crate ships binary blobs with no easy access to source code, I wouldn't ever consider depending on it.
If you can't prevent these blobs from infecting your system, you have to deal with the risk another way – locked-down containers on the server side, strict CSPs on the client side, and monitoring.
dgb23|4 years ago
Despite that, developers are building serious/complex websites with tons of custom functionality with WP, by extending it via the hooks that the theme and plugin system provide.
One of many problems with the above is that your whole default project structure is optimized for user workflows rather than developer workflows. Dependency management becomes even more complicated and fragile than it already is. So in terms of JS inclusions you get pre-compiled stuff instead of the source, because WP doesn't have a dependency and build system.
The best strategy to solve that is to _avoid_ dependencies, _especially_ plugins-level dependencies, like hell and have only a minimal vetted list of those. Most functionality plugins provide are again, optimized for users who will only ever touch the GUI and are typically completely unnecessary, too complex and are often painful to interact at the code level.
Plus as a kind of important aside: there is another issue with providing plugins with pre-compiled JS and other stuff without the source. I'm pretty sure it violates the GPL license[0] to do so or is at least a grey area. Would be happy to hear of more knowledgeable people about this issue.
TL;DR: When developing with WP, avoid dependencies and especially plugins. There is already enough accidental complexity as is.
[0] https://developer.wordpress.org/themes/getting-started/wordp...
bjpirt|4 years ago
But the other complementary approach is to lock down other things - so for example, if you're running in a container, make sure that container can only talk to the proxy in front of it. That way, even if there was some kind of malicious code running in one of the modules, there's no way for any data to get in or out (unless it finds a way of injecting into any web input/output, but then you need to be scanning for that too)
[1] https://github.com/aquasecurity/trivy
AKluge|4 years ago
Running a pen test against web apps can also be educational and amusing. ZAP is highly customizable, so you can extend it to cover particular areas of concern. https://www.zaproxy.org/getting-started/
duckmysick|4 years ago
Is there a tool like trivy that can help with that?
TekMol|4 years ago
This of course excludes the majority of packages out there. But apart from security, it has another benefit: These dependency very rarely break and need updates. So compared to projects with a more complex stack, projects with a lean stack are easier to maintain.
It would be great if there was a "single small file packages" movement so that more lean open source software will be created.
tfehring|4 years ago
I think it's reasonable to err on the side of rolling your own for simple stuff instead of `npm install is-even` or whatever. But using other people's software is a net positive for both productivity and security for sufficiently complex applications. And the range from "simple" to "complex" is a continuum and it's not trivial to decide where on that continuum to draw the line.
apples_oranges|4 years ago
danielsamuels|4 years ago
There are certainly npm authors doing this already, feross[1] is a good example. That means you get packages like is-buffer[2].
[1]: https://www.npmjs.com/~feross [2]: https://github.com/feross/is-buffer/blob/master/index.js
laurent123456|4 years ago
And if the package is not "small enough", I guess it means it needs to be re-implemented from scratch? If a company is happy to pay you for that (and is aware of it), why not, it's fun actually, but not very productive.
dd82|4 years ago
uh, no. what would be even better if TC39 did something beyond window dressing and JS gets a sane standard API so these idiotic requirements for API fill in are no longer required.
These packages are required solely because JS has a crappy API and a vacuum was filled. This increases the surface for supply chain attacks, a la ua-parser-js in Oct.
Other languages have their own issues. But they also have saner stdlibs so the attack vectors are different.
endymi0n|4 years ago
For example, putting that external software in a hardened container with network policies, non-root user, capability drops, readonly filesystem (,...) will go a long way towards securing it, even if there's a cleverly disguised backdoor you didn't manage to find.
Dumping your database is only half the fun if the app isn't able to send all the data to Alonistan...
onion2k|4 years ago
The only option is to flag them as either insecure or unchecked.
m0zg|4 years ago
dncornholio|4 years ago
livealight|4 years ago
The only way that I can think of getting around this is to have a hard requirement for a source registry - or asking the premium plugin producers to produce a SBOM like cyclonedx or spdx and evaluate that in lieu.
robin_reala|4 years ago
BjornW|4 years ago
tdrdt|4 years ago
Because the moment someone hits update on the package manager nothing will get updated and you won't receive potential dangerous updates you did not review first.
Edit: sorry this is not relevant to the question...
richardwhiuk|4 years ago
You'll then want tooling to periodically update your locked dependencies, so that you pick up fixes to security vulnerabilties. That wants to go through your CI.
2OEH8eoCRo0|4 years ago
tailspin2019|4 years ago
It’s a very good tip though. I must start doing this.
krageon|4 years ago
ashward|4 years ago
jbverschoor|4 years ago
TheRealBrianF|4 years ago
https://blog.sonatype.com/mapping-the-javascript-genome-for-...
chha|4 years ago
BjornW|4 years ago
snaveen|4 years ago
These projects help with repository best practices and does some level of npm package analysis based on rules.
snaveen|4 years ago
jimmont|4 years ago
aww_dang|4 years ago
At this point I can no longer hold my breath and hope that the Node.js trend goes away.
roofwellhams|4 years ago
orangepanda|4 years ago
KronisLV|4 years ago
That is only a valid stance to take while you're developing most of the "regular" software out there, but once you start dealing with finance data in an industry that's highly concerned with compliance and security you might get more demands forced upon you in regards to what you can or cannot do.
That's not to say that there exists a better auditing mechanism, short of allotting a large amount of your time to building all of your dependencies from source and checking all of their changes manually, which almost no one actually does in practice - it is indeed easier to lie about compliance and just shrug your shoulders when you get caught.
I do not, however, condone any of it. I believe that the industry is largely headed in the wrong direction - there are entire Linux distros that weigh in at less than 289 MB and that not a single codebase out there needs that much code to actually run. I briefly touched upon it in my blog article, "Never update anything" (the title is not to be taken at face value), which explored the nature of updates in our industry: https://blog.kronis.dev/articles/never-update-anything
Of course, sadly that doesn't actually help a person who is stuck with such a codebase and needs a solution now. I don't think there is one. And in regards to starting new projects, large amounts of dependencies can definitely creep up on you! It would be interesting to have a CLI tool that warns you about the amount or size of dependencies in your project, to get something like: "CI build aborted, the project exceeds your configured amount of dependencies: 30 libraries (10 MB total size). Please reconsider what you're importing in your own project. Here's a dependency graph: ..."
tompazourek|4 years ago
niros_valtos|4 years ago
From a detection standpoint, the free options are NPM audit and GitHub’s Dependabot, which are ok. A commercial option (e.g. Snyk, WhiteSource, BlackDuck) is typically more recommended to manage exceptions and get more accurate results (e.g. is the vulnerable code used by your code).
fergie|4 years ago
roland35|4 years ago
game_the0ry|4 years ago
politelemon|4 years ago
thih9|4 years ago
dotancohen|4 years ago
If you prefer a private discussion, my gmail username is the same as my HN username. Thank you!
vasilakisfil|4 years ago
BjornW|4 years ago
To give an example of my process thus far:
Someone in my team wants to see if we can use plugin X. I’m downloading the plugin to have a look at the code. Luckily this plugin has included a non-minified version of the js file. I can derive the use of npm packages from this file. Using Snyk I have a look at the first package mentioned. It’s axios. The included version is vulnerable (high & medium severity) and has been for almost a year (Note: the last version of the plugin is 3 months old and does not exclude this vulnerable version in it’s package.json which I found in a Github repo later on).
Since I have no package.json nor package-lock.json (all I have is the distributed build) I can’t easily update the npm package. I have no clue as to how this package relates to the other packages and how their version might depend on each other. Even if I would update the package, all other users of this plugin are still vulnerable. I contacted the plugin author. He tells me he will update the plugin as soon as possible. The plugin is (as of today) still not updated & has not released a new version. In the meantime there have been two new versions of the axios package released.
Every user of plugin X is still vulnerable to the issues mentioned on Snyk, but is this a real problem in this specific WordPress plugin context? I’m not sure how to interpret the high & medium severity in the context of this plugin. How exploitable are these issues & what is the impact of the exploits in the context of this plugin? Do I need to be a logged in user? Is this something which can be triggered by any visitor? What am I able to do when I can exploit these vulnerabilities? I can only try to find answers to these questions if I’m willing to invest a lot more time into this, which more or less beats the purpose of using a ‘ready-made’ WordPress plugin. And this is just one package of multiple npm packages used in this plugin. Packages which also have their own dependencies as well….
At this moment I’m wondering if any WordPress plugin using npm packages can be trusted at all.
ps: The way the npm ecosystem is structured is, in my view at least, problematic. Often packages are not like libraries as I’d expect, but look more like a function call or method call. I’d prefer to write these short pieces of code myself instead of depending on external code which also includes extra risks. The very rapid release schedules makes it even harder to trust external software (like a WordPress plugin) using npm packages as it seems they cannot keep up with it.
I’m sorry if this seems like a npm rant, but I’m seriously looking for methods on how to deal with these issues so we can use external software (like WordPress plugins) built with npm packages.
TekMol|4 years ago
evandwight|4 years ago
englund|4 years ago
I'd be curious to hear if anyone can think of possible applications of it in security auditing.
unknown|4 years ago
[deleted]
laurent92|4 years ago
I assume that if I were a sensitive institution, I would pay people to inspect those dependencies and discover vulnerabilities.
The medium term would be to publish a bug bounty, so researchers are incentivized to find vulnerabilities.
niros_valtos|4 years ago