Another wave of typosquat packages hit a major registry, and the fix everyone proposes still won't ship
Published by RodHat · Updated

A batch of typosquatted packages got pulled from a major registry this week after a researcher caught them exfiltrating environment variables on install. Names one or two characters off from popular libraries, publish timestamps clustered together, obviously automated. Standard stuff, as these things go now.
What’s not standard, what’s never standard, is any actual structural fix showing up afterward. Every time this happens there’s a wave of “we need mandatory namespace verification” and “publishers should require 2FA” and every one of those things is correct and every one of those things has been correct for about eight years without becoming policy.
Why the obvious fixes don’t ship
Not because the registries don’t care; I’ll extend that much good faith. It’s because every fix
that would actually move the needle also adds friction to the exact workflow that made these
ecosystems grow in the first place: publish, no gatekeeper, no review queue, instant global
availability. That frictionlessness is the feature. The typosquats are the tax on the feature. Nobody
running the registry wants to be the one who traded growth-rate for safety, so the tax gets paid in
someone else’s incident report instead.
I’m not saying frictionless publishing was wrong. It’s the reason these ecosystems have the library coverage they do. I’m saying pretending the tradeoff doesn’t exist, cycle after cycle, is how you end up relearning the same lesson every few months with a different package name in the postmortem.
What actually protects you, since the registry isn’t going to
- Pin exact versions and hashes in lockfiles, and treat an unreviewed lockfile diff as a code review item, not a rubber stamp.
- Run install scripts in a sandbox or disable them outright where your build allows it. Most of
these attacks fire on
postinstall. - Mirror or vendor anything load-bearing. If a typosquat gets published under a name close to a dependency you pull fifty times a day in CI, you want your CI pulling from a cache you control, not resolving live against the public registry every run.
None of this is exotic advice. It’s the same discipline people applied to apt sources and RPM
repos back when “supply chain” wasn’t a term anyone used because it was just called “not trusting
random servers on the internet by default.” We reinvented the problem. We can reinvent the caution
too.
The pattern has gotten worse since 2024, not better
Worth being specific about the trajectory here: automated typosquat tooling has gotten cheap enough that the same attacker can register and publish hundreds of variants in an afternoon. The July 2026 wave had package names that weren’t just one-character transpositions; some were plausible abbreviations, some used lookalike Unicode characters that render identically in most terminal fonts. The old “just spell-check your imports” advice doesn’t cover the Unicode variant case unless your tooling is specifically checking for it, and most isn’t.
The install-time exfiltration angle has also gotten more targeted. Early typosquats would just
grab ~/.ssh/ and ~/.aws/ and ship the whole directory. More recent ones are selective: they
look for CI-specific variables (CI, GITHUB_TOKEN, NPM_TOKEN), grab only those, and exit
cleanly without writing any files that a basic filesystem audit would catch. The artifact looks
like a normal install unless you’re watching network traffic or running the install in a sandbox
with egress blocked.
Blocking outbound network from your CI install step, even selectively, catches this entire class.
An npm install step has no legitimate reason to make outbound connections to arbitrary IPs. If
your build system allows you to restrict egress during the install phase, do it. It’s a one-line
config change on most platforms and it turns a credential-exfiltration attack into a noisy failed
install that shows up in logs.
The TLS debugging tip covers inspecting what connections your tooling is actually making, which is the manual version of the same check.