Attackers Are Not After Your Service
The other day, a development partner asked me, “Just do these three things.”
npm, pip, bundler. It was a setting to switch each package retrieval to go through a proxy with security checks.
Honestly, my first reaction was, “Wait, do I even need to do that?”
The reason: I don’t have access rights to that partner’s GitHub. I only touch a small part of the shared work, and I can’t get into their repository or the cloud citadel on their side. So even if something dangerous slipped in, the damage would fall on “the people with the permissions,” and it wouldn’t really concern an outsider like me — or so my reasoning went. It sounded plausible even to me.
Still, I decided to do exactly as I was told. The token had already been handed over, and it was just typing a few lines of commands. I put in a deliberately prepared “malicious package” for testing, confirmed it was properly rejected with a 403, and the work itself was done in five minutes.
Then, after finishing, I started looking into it, and gradually came to realize that my initial reasoning had missed the point entirely.
To begin with, what exactly do these kinds of attacks steal?
The complacency of “I don’t have access rights, so it doesn’t concern me”
My naive understanding was this: “They hijack your GitHub or AWS access and do whatever they want in your repositories or cloud.” News headlines mostly wear that same face.
The “I can’t get into my partner’s GitHub, so it’s not my problem” from the opening, and my own reaction of “AWS keys being targeted doesn’t really register with me” since I barely use AWS — these come from the same root. I was trying to gauge my own level of risk by access rights and service names.
That’s the trap. The moment you try to measure it that way, you get the judgment wrong. As I’ll explain below, the essence of this attack lies outside the question of “which service, and what permissions do I have on it.”
A worm named Shai-Hulud
In September 2025, the first “self-replicating worm” was observed on npm. Shai-Hulud (named after the desert sandworm). Starting from a small package called @ctrl/tinycolor, the infection spread to more than 500 packages.
The mechanism was nasty. Once a maintainer’s account was hijacked, the malware automatically rewrote and republished that maintainer’s other packages. Instead of a human planting them one by one, they multiplied on their own. Literally a worm.
Then in November, a more vicious second wave arrived. Shai-Hulud 2.0, with a repository description reading “Sha1-Hulud: The Second Coming.” By some counts, 796 packages were hijacked, and their combined weekly download count exceeded 20 million. Some estimates put the number of affected repositories in the tens of thousands. It shifted to firing at the pre-install stage, further widening the scope of damage. It even came with an aggressive bonus: if it failed, it would try to destroy the victim’s home directory.
And the story doesn’t end in the past tense. Entering 2026, this lineage flared back up as “Mini Shai-Hulud,” growing into an even bigger wave in May. In just 48 hours on May 11-12, around 170 packages and more than 400 versions were contaminated, reaching even widely used namespaces like @tanstack, @mistralai, and @uipath. And this time it spread not just to npm but simultaneously to PyPI, dragging in the world of pip install as well. Later that month, a separate wave scattered over 300 versions in just over 20 minutes, and new attacks were being observed as recently as June. What’s more troubling, some of the waves didn’t even bother stealing credentials — they hijacked the legitimate release pipeline and distributed themselves “authentically signed.” Even the defensive line of “trust the publisher” has partly been broken.
I only heard about this myself quite recently. That’s no surprise, since this isn’t a closed case — it’s still actively burning right now.
The essence isn’t stealing a “service” — it’s stealing an “environment”
This is the part I most wanted to write about today.
The essence of this attack isn’t “targeting a specific service.” It’s “sweeping up, indiscriminately, whatever secrets sit in the environment.”
I’m not a security expert, so what follows is secondhand knowledge, but roughly speaking, it works like this. First, it dumps the entirety of process.env (the list of environment variables) and picks up whatever tokens are in there. It directly reads cloud credential files lying around on disk. And the crowning move: it downloads and uses a legitimate tool called TruffleHog.
TruffleHog is originally a proper secret scanner meant for developers to find “API keys or passwords that accidentally got left in code.” It can detect secrets for hundreds of kinds of services. Attackers use it in reverse. In other words, whatever secrets remain in your environment get dug out wholesale, regardless of the type of service. On top of that, it hits the metadata endpoints of AWS, GCP, and Azure to seize even cloud workload credentials.
So the question was framed wrong from the start. It’s not “will GitHub or AWS be targeted?” The correct framing is this: “Whatever was sitting in your .env or CI gets taken away entirely, regardless of the service name.”
Stripe keys, database connection strings, Slack tokens, SSH keys — all fair game. In a modern development environment, LLM API keys are probably plugged into .env too, but those get swept up just the same, as nothing more than “a secret that happened to be sitting there.” If it’s there, it gets taken. That’s all there is to it.
Here’s where my opening reasoning falls apart. Sure, I can’t get into my partner’s GitHub. But the moment I ran their project with npm install on my own machine, the danger shifted to “my own machine.” Whether I have access rights or not is irrelevant. What gets stolen is my own token, carelessly sitting on my own laptop. Far from being “safe because I’m an outsider,” my environment itself becomes the entry point, exactly as it is.
Taking it all, without even checking whether it’s there
Here we need to switch our way of thinking.
We usually think about security “individually.” We protect this service’s token this way, we store that API key that way. The image is one of assigning a countermeasure to each item, one at a time.
But attackers don’t see it that way. They don’t check one by one whether “this key exists” or “that credential exists.” They take the entire environment, wholesale. Sorting through the contents can happen leisurely, after the theft. So the idea of “carefully guarding only the important things” only half-works against an opponent who scoops up everything at once.
And the place packed fullest of contents is CI/CD. Build pipelines usually hold production secrets, with strong permissions, carelessly. And npm’s install-time hooks, as I understand it, become an entry point that runs code with the permissions of the user who did the install. With a single npm install, a structural pathway is already laid out for that environment’s secrets to be extracted.
Vibe coding throws that entry point wide open
Lately, so-called vibe coding has become commonplace. Ask an AI, “build me something like this,” and it picks out libraries that seem necessary, runs pip install or npm install on its own, and gets things to a working state. It’s fast, and it’s fun. I use it often myself.
But laying it alongside today’s topic, this is fairly dangerous.
The pleasure of vibe coding is supported by “not examining things yourself.” Checking exactly which packages, at which versions, with what install-time scripts bundled in — do that meticulously, and you lose that lightness. Without being conscious of it, without really understanding it, you just install it and move on. That’s the substance of the experience.
Now layer that against the fact mentioned earlier — that it “fires with a single npm install,” that “it spread to PyPI too.” Even back when humans examined and installed things one at a time, everything still got swept away wholesale. Now, something that isn’t even human does it dozens of times over, without any awareness at all. “Just install it for now” can itself become the single biggest weakness.
There’s an ironic punch line too. In the May TanStack wave, the malicious commit the attackers slipped in carried a forged signature impersonating the official account of an AI coding assistant tool, and it even included a trick to skip CI. The ease of leaving things to AI, and an attack that impersonates AI, meet in the very same place.
Not being an expert is exactly why I need to keep a basic stance
Honestly, I’m not a systems engineer, nor am I a security specialist. So everything explained above is only as far as I researched and understood it, and there are surely rough edges from the perspective of someone knowledgeable. Feel free to take it with a grain of salt.
Still, there’s one stance from this whole episode that clicked into place for me. The sense of security based on “I don’t use that service” or “I don’t have permission to get in there” — grounded in access rights or service names — was entirely misguided. If what needs protecting isn’t the “service” but the “environment itself,” then the very unit of stock-taking changes.
What CISA and the defense guides from various companies say in unison is simple but harsh. “Once infected, act on the assumption that every secret that was in that development or CI environment has been stolen.” Don’t just rotate the keys for the service reported as breached — rotate every token that was sitting in that environment. Not taking comfort in a service’s name seems to be the only sound stance.
In the end, where is the weakest boundary?
Back to the “just do these three things” from the opening.
That proxy was a good move, closing off one entry point through which malicious packages could get in. In fact, the malicious test package was cleanly rejected.
But what truly needs protecting isn’t just the “entry point.” What needs protecting is the pile of secrets itself — carelessly stacked up on your laptop and in your CI, without even a service-name label attached.
Attackers aren’t targeting your service. What they’re targeting is the state of clutter at your fingertips.
The weakest boundary wasn’t the product’s security design. It was the developer’s desk.
Reference links
- CISA, “Widespread Supply Chain Compromise Impacting npm Ecosystem”: https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem
- Datadog Security Labs, “The Shai-Hulud 2.0 npm worm”: https://securitylabs.datadoghq.com/articles/shai-hulud-2.0-npm-worm/
- Akamai, “Mini Shai-Hulud: The Worm Returns and Goes Public”: https://www.akamai.com/blog/security-research/mini-shai-hulud-worm-returns-goes-public
- Snyk, “TanStack npm Packages Hit by Mini Shai-Hulud”: https://snyk.io/blog/tanstack-npm-packages-compromised/
- Palo Alto Networks Unit 42, “The npm Threat Landscape”: https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks/
This piece was conceived and directed by Kuzuryu, written with AI.
Originally published in Japanese at https://clazytech.com/2026/06/1621/. Translated with LLM assistance and reviewed before publication.