North Korean Hackers Just Poisoned 1,700 npm and PyPI Packages — Here's How to Not Get Owned
North Korean Hackers Just Poisoned 1,700 npm and PyPI Packages — Here's How to Not Get Owned
A North Korean hacking group called UNC1069 just got caught pushing over 1,700 malicious packages across npm, PyPI, Go modules, and Rust crates. Not 17. Not 170. Seventeen hundred packages, spread across every major package ecosystem that developers use daily.
If you ran npm install this week without thinking about it — and let's be real, we all do — this is the post where you start thinking about it.
How the Attack Works
The playbook isn't new, but the scale is. UNC1069 used a combination of techniques that have been around for years:
Typosquatting. They create packages with names that are one character off from popular libraries. You type npm install lodsah instead of lodash and congratulations, you've just installed a package that phones home to a server in Pyongyang. Or wherever. The point is, it's not your server.
Dependency confusion. If your project has private internal packages, an attacker can publish a public package with the same name but a higher version number. Many package managers will prefer the public one. Your build pipeline pulls the malicious version, runs its install scripts, and now someone else has access to your environment variables.
Compromised maintainer accounts. Sometimes they don't even bother with the fakes — they hack the account of a real maintainer and push a malicious update to a legitimate package. Harder to detect because the package name is real, the publisher history is real, and the change might be buried in a minor version bump.
The malicious payloads range from credential stealers to cryptocurrency miners to full reverse shells. Some packages sat in registries for weeks before being discovered.
Why Solo Devs Are the Softest Target
Big companies have security teams that run dependency audits as part of their CI/CD pipeline. They have policies about approved packages. They have people whose literal job is watching for supply chain attacks.
You have npm install and trust.
I'm not being snarky — this is the reality for every solo developer and small team. We install packages based on star counts, download numbers, and whether the README looks legit. We don't verify the publisher. We don't read the source code of our dependencies. We definitely don't read the source code of our dependencies' dependencies.
And that's what makes supply chain attacks so effective against indie builders. The attack surface isn't your code — it's the 847 packages in your node_modules folder that you've never looked at.
What You Actually Do About This
The goal here isn't to become paranoid about every package. It's to add a few layers of defense that take about 15 minutes to set up and then run automatically.
Use lockfiles. Commit them. If you're not committing your package-lock.json or pnpm-lock.yaml, start now. Lockfiles pin your dependencies to exact versions. Without them, a minor version bump that introduces malicious code will be silently pulled in on your next install.
Run npm audit and actually look at the output. I know. It's always full of warnings and most of them are theoretical. But get in the habit of running it before deploying. If something critical shows up, fix it.
Install Socket.dev or Snyk. Socket is particularly good for this — it analyzes what packages actually do at runtime, not just whether they have known CVEs. It'll flag a package that suddenly starts making network requests when it shouldn't be. The free tiers are sufficient for solo projects.
Pin your dependencies. Instead of "lodash": "^4.17.21" (which allows any compatible minor version), use "lodash": "4.17.21" (exact version). Yes, you'll need to manually bump versions. That's the point — manual bumps mean you see what changed.
Enable 2FA on your npm account. If you publish packages, this prevents someone from compromising your account and pushing malicious updates under your name.
Use Dependabot or Renovate. These tools create pull requests when your dependencies have updates. They won't catch malicious packages, but they keep you current on security patches and make dependency management a pull request review rather than a blind npm update.
The Bigger Picture
This isn't a one-off. Supply chain attacks are accelerating because they're efficient. One compromised package can hit thousands of projects. And the barrier to entry is laughably low — anyone can publish an npm package.
The JavaScript ecosystem is especially vulnerable because of its culture of tiny packages. When a single project has hundreds of dependencies, the surface area for attack is enormous. The Rust and Go ecosystems are smaller but growing, and UNC1069 targeting them signals that no ecosystem is safe.
For solo builders, the uncomfortable truth is that perfect security is impossible. You're going to install packages you haven't audited. You're going to trust maintainers you don't know. The best you can do is add friction between "package is installed" and "package has access to my secrets" — lockfiles, auditing tools, and the habit of pausing before running install scripts from unfamiliar sources.
It's not sexy. It's not a newsletter thread about 10x productivity. But it's the kind of boring operational hygiene that keeps your project and your users safe.
Go check your node_modules. Seriously.