Your AI coding agent doesn't check what it's installing, and attackers know it
165 malicious npm and PyPI packages surfaced in a single week in July 2026, several aimed at AI coding tools. Here's what that means before you install one.
By Gabriel Lara, Developer Relations, Norbelys
Founder-reviewed ·How we research and correct articles
When a developer installs a package by hand, there’s usually at least a half-second of friction: a glance at the download count, a check that the maintainer looks legitimate, maybe a search for the package name plus “malware” if something feels off. An AI coding agent scaffolding your project doesn’t do any of that by default. It sees an import statement is needed, it runs the install command, and it moves on — which is exactly the gap attackers spent July 2026 exploiting.
The week in numbers
Xygeni’s weekly scan attributed the count to “automated bulk publishing against registries with no meaningful pre-publication review” — attackers aren’t hand-crafting each malicious package, they’re generating and publishing variants faster than registries or human reviewers can pull them. Two named incidents from the same month make the AI-tooling targeting concrete rather than theoretical:
- Jscrambler npm packages, compromised July 11 using stolen publishing credentials, shipped hidden native binaries designed to harvest secrets from “a wide range of applications, including cloud providers, cryptocurrency wallets, and AI coding assistants” specifically, per Rescana’s advisory.
- Four packages in the
@asyncapinamespace, totaling over three million weekly downloads, were compromised July 14 to deliver credential-stealing malware that exfiltrates data to an attacker-controlled server, according to Datadog Security Labs’ breakdown of the attack.
Neither of these required a sophisticated zero-day. Both required someone —
or something — to run npm install on a package name that looked
legitimate.
Why an agent makes this worse, not just faster
The problem isn’t that AI coding agents install packages. It’s what’s missing from how they do it, compared to how a careful developer does it:
An agent under instructions to “add a CSV parser” or “wire up the mail client” resolves the fastest path to a working import, and a freshly published, name-squatted, or typo-adjacent package satisfies that just as well as the legitimate one — often better, since it hasn’t accumulated the version history that would otherwise flag it as unusual. Multiply that across every project where a coding agent has standing permission to run install commands unattended, and a single well-placed malicious package can reach far more machines, far faster, than a phishing email ever could.
The payloads aren’t subtle about what they’re after, either: cloud provider credentials, CI/CD secrets, and — per the Jscrambler advisory specifically — whatever an AI coding assistant happens to have cached or configured locally. That includes API keys for the services you’re building against, which is the part that should get an outbound-email team’s attention.
The trust signals an agent doesn’t have
A human developer builds up a rough intuition for “does this package look right” over years of installing dependencies: download counts that make sense for what the package claims to do, a maintainer history longer than a few days, a changelog that reads like normal iterative work rather than a burst of versions published minutes apart. None of that intuition transfers to an agent unless someone explicitly built the check into its workflow — and most agent setups don’t, because “install the dependency and keep moving” is the faster path to a working demo.
That gap is exactly what the two July compromises exploited. The Jscrambler attack used stolen legitimate publishing credentials, so the malicious versions came from the real, previously-trusted package — there was no new, suspicious name for even a careful human to catch, let alone an agent with no download-history check at all. The AsyncAPI compromise hit a namespace with over three million weekly downloads, meaning the “this package is popular, it must be fine” heuristic — the one shortcut most humans and most agents implicitly rely on — was exactly backwards for that one window of time.
What this means if you’re building on an email API
If you or your team use an AI coding agent — Claude Code, Cursor, Windsurf,
or anything similar — to scaffold integrations against the Norbelys
API, the exposure isn’t hypothetical. A compromised dependency
pulled into that project during a normal npm install can read whatever
credentials are sitting in your environment, including a sending API key with
more scope than the task in front of the agent actually needed.
The mitigations are unglamorous but they work:
- Scope the key before you hand it to an agent’s environment, not after.
A key limited to the one workspace and the one operation a project actually
needs caps what a compromised dependency can reach,
even if the agent’s
node_modulesgets poisoned. - Prefer the official SDKs and the MCP server over hand-rolled HTTP calls an agent assembles from scratch — a smaller, audited dependency surface is a smaller attack surface, and it’s one fewer place for an agent to reach for an unfamiliar package mid-task.
- Pin dependency versions and review lockfile diffs, especially in any repo an agent has unattended install permissions in. A version bump you didn’t ask for is exactly the shape this attack takes.
- Rotate keys on a schedule, not just on suspicion. If a credential was exposed during the window before you noticed, rotation is the only control that actually closes it.
Norbelys’s npm and Python SDKs are generated from one typed contract and published under a single verified namespace — there’s no ambiguity for an agent (or a developer) to resolve about which package is the real one. And every key you issue through the dashboard is scoped to one workspace by design, so a compromised dependency in a side project never becomes a compromised sending domain. See the plans and connect your first key the way it’s meant to be scoped — narrow, named, and revocable the moment something looks wrong.