Readit News logoReadit News
Posted by u/bodash 3 months ago
Show HN: Tips to stay safe from NPM supply chain attacksgithub.com/bodadotsh/npm-...
Hi everyone, given the recent increase of attacks on the NPM supply chain, I've put together a list of tips and tricks to help developers stay secure on this specific topic: https://github.com/bodadotsh/npm-security-best-practices

I'd love for you to check it out, and contribute your own insights and best practices to make this a comprehensive resource for the community.

Cheers!

HoyaSaxa · 3 months ago
For most projects, overriding every single transitive dependencies to be pinned is impractical.

Instead, for those using npm, I'd highly suggest using `npm ci` both locally and of course on CI/CD. This will ensure the (transitive) dependencies pinned in the lockfile are used.

TIL on the `npm install --before="$(date -v -1d)"` trick; thanks for that! Using that to update (transitive) dependencies should be really helpful.

For those using GitHub Actions, I'd also recommend taking advantage of the new dependabot cooldown feature to reduce the likelihood of an incident. Also make sure to pin all GitHub Action dependencies to a sha and enforce that at the GitHub repo/account level.

knlsn · 3 months ago
For GitHub Actions, i found http://safedep.io/ to be helpful, not only it guard against known attacks, but also it has its own malware detection engine.
kpcyrd · 3 months ago
Also, don't use npx.

With the colors incident back in 2022, random stuff started to break not when people updated their dependencies, but immediately, because npx would resolve dependencies when the command is executed.

This means it's not really possible to reason about what code is going to execute, and forensics is going to have a really hard time figuring out what a computer has executed.

If your software uses npx in any capacity, you've auto-failed the SBOM compliance checkbox.

potamic · 3 months ago
> npx would resolve dependencies when the command is executed

I hate that this is becoming a thing. I was pretty miffed some time back when I realized go build just went ahead and installed a whole new version of golang on my machine. These are devtools ffs, why so much mollycoddling! And what happened to half a century of good conventions where the default is always to prompt?

grim_io · 3 months ago
And what happened to half a century of good conventions where the default is always to prompt?

The good old "be careful what you wish for" :)

condiment · 3 months ago
What makes node supply chain attacks so dangerous is the CI/CD pattern whereby all dependencies are downloaded from the internet every time a build is created. NPM attacks move fast.

I previously worked in an environment where our ci servers weren't internet-connected. One of the things we did get get node builds to work was we had 'node_modules' for our projects in a separate repository that got joined with our source code in CI to complete a build. When a developer added a dependency, they had to update this repo from their local version. It was annoying to have to synchronize two repositories, but this ended up being a forcing function for the development team to adopt several of the suggestions listed here. When you see a PR with a massive diff for a small dependency change, eyebrows raise and the team starts conversations about how to improve things.

minitech · 3 months ago
Lockfiles are a more standard and probably better way to do this. (People do need to pay more attention to lockfile diffs.)
DanHulton · 3 months ago
And if you want to get the same "we serve the code directly" benefit as well, you can set up an npm proxy and require its use. That way you're getting a very specific version, and downloading that version from a location you control.

(And then for the ultimate level of "slow your project to a crawl, but hey at least it's really secure", you can only allow versions that pass an internal security review to be added to the proxy and disable automatic fetching of un-cached versions. Ain't no sneaky code getting in unawares there!)

abejfehr · 3 months ago
These tips are great, but they don’t address some of the core ways that these supply chain attacks may happen: global modules and npm modules installed with editor extensions.

So `yarn global add nx` will still install the latest version by default, unless you specifically have a `~/.yarnrc` disallowing lifecycle scripts they will still be executed. Using a package manager that doesn’t allow lifecycle scripts by default is the solution here I guess.

I don’t know what the solution is for stuff like [this](https://github.com/nrwl/nx-console/blob/d2fa56509679fc942bbc...) where the editor plugin automatically uses the latest version, or where in general you have little control over what version is used. Any eslint, typescript, nx, prettier, etc plugin will presumably depend on their corresponding package from npm, and if any of those gets compromised then just installing an editor extension could be enough to get you in trouble.

zygentoma · 3 months ago
Somehow it is missing the "read the code of your dependency" step … :)

Even occasionally having a glance (e.g. when reading the docs) might be super helpful in discovering strange things going on.

invaliduser · 3 months ago
Or maybe just read the commits between now and a reasonable date far enough in the past so that if there is some hostile code injected before that point in time, then at least you will share the walk of shame with a lot of people and you can play the sound of "who could have guessed?"
dns_snek · 3 months ago
There's no point in reading the code in the Git repository or its commit history because that's not the code that you're actually executing. You have to read what's in your node_modules, everything else is irrelevant.
ashishbijlani · 3 months ago
Plug: I've been building a tool to detect software supply-chain cyberattacks: https://github.com/ossillate-inc/packj

Packj uses static+dynamic code/behavioral analysis to scan for indicators of compromise (e.g., spawning of shell, use of SSH keys, network communication, use of decode+eval, etc). It also checks for several metadata attributes to detect impersonating packages (typo squatting).

lrvick · 3 months ago
Every decent malware author just adds tools like these to their test suites, and only release new malware that evades all detection.

That game of cat and mouse never ends.

The only solution is just actually reviewing the code we ship to our customers. Yes, even the code we copied off the internet with a magic "npm install" command.

dwoldrich · 3 months ago
I appreciate all this guidance. I hope Node developers read it all and consider adopting most/all of it.

Node and the NPM ecosystem has been so productive for me and package.json scripts got me more into shell scripting than I ever thought I would.

All that said, there are some major insecurity deal breakers that frighten me when using Node in public-facing services.

Sneaking in compiled native binary blobs as part of NPM install, transitive dependencies with unpinned versions, the vast wasteland of unmaintained packages in NPM ... Node just needs to be superceded, I feel like.

It would be really great for a newer tech company with deep pockets like Tesla to pull a Sun Microsystems and release a new secure-by-design OS and language stack - maybe in support of a modernized hardware platform offering.

My preference would be for a deeper standard library like the jdk. I would like some sort of digital provenance that runs from the dev environment, through the os and package manager, through to all device types all the way through to the one and only global app store (or an enterprise-hosted proxy.) The whole kit and kaboodle signed and delivered at all levels.

I would like more energy efficient network hosting and service delivery patterns codified.

I would like public developer guilds with certs not as a prereq for employment, but rather to encourage developers to have something to show for their training other than a nebulous college diploma. Senior guildsmen can present their work products for review as an ongoing proof of their craftsmanship.

fergie · 3 months ago
Huge props for point 13 which is basically the crux of the matter, and often overlooked.

Personally I would like to see more awareness around the dangers of blindly trusting compiled javascript (and non-human-readable code generally).