Browse the blog
Sentrint Blog
AI-built apps · Risks

The package was real, popular and compromised. Your agent installed it anyway

Slopsquatting is about fake package names. This is the opposite problem: real, popular packages get compromised at the source, and an install script runs on your machine before you have read a line. Lockfiles, install scripts disabled by default and short-lived tokens are what actually help.

Most advice about dependency risk assumes you chose the dependency badly. The Shai-Hulud family assumes you chose correctly, and takes the package you were right to trust.

It started in September 2025 with phished maintainer accounts and a payload that harvested credentials from process.env, then used the stolen npm token to publish itself into the next set of packages downstream. The August 2026 wave, which Microsoft and Elastic tracked as CHAINDROP, reached the keyv caching library and its neighbours and covered more than 400 packages representing over two billion monthly installs inside a few hours.

Why does this hit AI-built projects harder?

Not because the malware cares what wrote your code. Because of what happens between "add caching to this" and a working feature.

An agent resolves a package, runs the install, sees a green build and moves on. That entire sequence happens without anyone reading a version number, and the install itself executes arbitrary code through the postinstall hook before your app has run once. The gap between deciding to use a library and having its code execute as you is now measured in seconds and involves no human judgement at all.

There is a second reason, and it is the uncomfortable one. Agent-built projects tend to accumulate dependencies faster, because asking for a library is cheaper than writing forty lines, and every added package is another maintainer account whose two-factor setup you are implicitly trusting.

What does the payload actually take?

The published analyses agree on the shape. It reads environment variables for npm, GitHub, AWS and GCP credentials, then runs TruffleHog, a legitimate secret-scanning tool, across the filesystem to find several hundred more kinds of token that were not in the environment.

Anything it finds gets exfiltrated, and the npm token gets used immediately to publish a poisoned version of whatever else that account maintains. That is the self-replication, and it is why a single phished maintainer becomes four hundred packages rather than one.

The part that outlives the incident is the credentials. Cleaning the malware off a machine does nothing about a token that left it three days ago, and reports after the 2025 wave found large numbers of stolen credentials still valid months later because nobody rotated what they could not prove was taken.

How do I tell whether I was hit?

Four things to look at, none of which need a security tool. Take them in this order, because the first is the cheapest and catches the most.

Check your lockfile diffs. Open the last few commits that changed package-lock.json or pnpm-lock.yaml and look for versions that moved without you asking. A patch bump on a transitive dependency, arriving in a commit about something else entirely, is exactly what this looks like from the inside.

Look for repositories you did not create. The 2025 wave published stolen data into new public repositories on the victim's own GitHub account, often with a distinctive name. Open your repository list and read it, including the ones you would normally scroll past.

Read your npm account's publish history. If a package you maintain has a version you did not publish, you are not investigating any more, you are responding.

Check token age. Any npm, GitHub, AWS or GCP token that existed during a wave and has not been rotated since is a token you cannot make claims about.

What actually reduces the risk?

Ordered by how much they buy you for the effort:

  1. Commit your lockfile and install from it. npm ci installs exactly what the lockfile says. npm install is free to resolve something newer, which is the whole attack path, and an agent will happily run either.
  2. Turn install scripts off by default. npm config set ignore-scripts true stops postinstall code running on every install. Some packages genuinely need it, and re-enabling for those few is a decision you make deliberately rather than a door you leave open permanently.
  3. Stop keeping long-lived tokens in your environment. A classic npm token in .npmrc sits there until somebody takes it. Trusted publishing and short-lived credentials mean the thing on your disk expires before it is useful.
  4. Delay upgrades on purpose. Most of these waves are detected and pulled within hours. A policy of not installing anything published in the last day or two costs you almost nothing and removes almost the entire window.
  5. Keep a dependency inventory you can actually query. When the next advisory names a package, the question is whether you have it, at what version, in which service. If answering that takes an afternoon, you will not answer it.

Where this sits next to your other risks

Honestly? Below the ones in your own code, for most people reading this. A compromised dependency is a real and increasing threat, and it is also the one with the most people watching it: registries pull packages, researchers publish within hours, and advisories reach you.

The missing authorisation check in your own repository has none of that. Nobody is monitoring it, nobody will publish an advisory, and the only event that surfaces it is somebody finding it. That is where Sentrint spends its attention: it reads your whole repository, reports what an attacker would reach first in plain English, and gives you a fix you can paste back into the tool that wrote the code. The first scan is free and needs no card, and it inventories your dependencies while it is in there.

Do the lockfile and the install scripts today regardless. Between them they take ten minutes and they close the path this whole family of attacks depends on.