›bobbyencoded_
/posts/newsletter/about
/posts/newsletter/about

The Decode

The week's AI & software news, decoded.

Subscribe →

// © 2026 BobbyEncoded Inc. — A Canadian corporation

← Back to Blog

The Decode #002

Valid Provenance, Still Malware

July 17, 2026 · 6 min read

The Decode, Security, Supply Chain, npm, GitHub Actions

The Decode is back, and it's weekly now. One lead story explained properly, a few quick hits, and sources for everything. Fridays.

This week's lead is a supply chain attack that broke two things a lot of us treat as safety nets. The malicious packages had valid provenance, and they ran without any install script. If your mental model of npm security is "check the provenance badge and install with --ignore-scripts", this one is worth ten minutes.

What happened

On Tuesday, July 14, someone published poisoned versions of four packages from the AsyncAPI project, a widely used toolkit for describing event-driven APIs. Microsoft's security team published a detailed breakdown the next day. By its count, five malicious versions across four packages went out within roughly 90 minutes:

  • @asyncapi/specs 6.11.2-alpha.1 and 6.11.2
  • @asyncapi/generator 3.3.1
  • @asyncapi/generator-components 0.7.1
  • @asyncapi/generator-helpers 1.1.1

@asyncapi/specs is a transitive dependency of many AsyncAPI tools, so a lot of people who never typed "asyncapi" could have pulled it in. Security Affairs reports the packages have over 2 million weekly downloads combined.

How it worked

Step 1: a workflow that trusted a pull request. The project had a docs-preview workflow triggered by pull_request_target. That trigger runs in the context of the base repository, with its secrets and a privileged token, and this workflow checked out the code from the incoming pull request. An attacker opened a PR whose content was designed to fetch and run JavaScript from an outside site. Microsoft is careful here: the public logs don't prove exactly how a credential was obtained. They do show that the privileged workflow processed the malicious commit, and that pushes authenticated as the project's bot account followed.

Step 2: the real release pipeline did the publishing. The attacker didn't need an npm token. Pushing as asyncapi-bot triggered the project's normal release workflows, which publish to npm through trusted publishing with GitHub OIDC. So the packages went out through the legitimate path, under the legitimate identity.

Step 3: provenance said everything was fine. All five versions carried valid provenance attestations. They correctly named the real repositories, the real commits and the real workflows. Microsoft's point is the one to remember: provenance tells you where and how a package was built. It can't tell you whether the commit that triggered the build was authorized.

Step 4: the payload ran on import. There were no preinstall or postinstall hooks. The loader sat inside ordinary source files and ran the moment your code did require or import. It spawned a hidden, detached Node.js process, which downloaded a large second stage from IPFS and executed it. Microsoft describes the result as a remote access tool with command-and-control, persistence on Windows, Linux and macOS, and several fallback channels.

Analyses differ on how dangerous this build was. Microsoft says modules for credential harvesting and self-propagation were present but disabled in this build. OX Security's analysis, as reported by Security Affairs, describes it as an active stealer that tries to republish itself using any npm, PyPI or Cargo tokens it finds. Either way, if you imported one of these versions, treat the machine as compromised.

Why this matters if you build software

I build iOS, Android and Mac apps now, so it's tempting to think of npm as someone else's problem. It isn't. The websites for my apps are built on npm packages, a lot of developer tooling arrives through npm, and CI pipelines install from it all day.

Here's how I read it through a systems lens:

  • --ignore-scripts is a filter for one trigger, not a sandbox. It stops install hooks. Anything that runs your code (tests, a build, a dev server) imports your dependencies, and that's enough.
  • Coding agents widen the trigger. An agent that runs npm test to check its own work is importing every dependency in the tree. A payload that waits for import doesn't need you to do anything unusual.
  • Provenance is an audit trail, not a verdict. It's still valuable, because it let investigators reconstruct exactly which workflow published what. But a valid badge on a package means "built by this pipeline", and here the pipeline itself had been hijacked.
  • The weak link was CI configuration. pull_request_target plus a checkout of untrusted code is a known dangerous combination. Microsoft notes a proof of concept was raised in April and a proposal to split untrusted builds from secret-bearing steps was still under review.

What I'd check this week

Microsoft's recommendations, in the order I'd do them:

  1. Search lockfiles and caches for the five versions above, including transitive references and shared CI caches.
  2. Pin known-good versions: @asyncapi/specs 6.11.1 or earlier, @asyncapi/generator 3.3.0, generator-components 0.7.0, generator-helpers 1.1.0.
  3. Rotate credentials from a clean machine if anything imported a bad version.
  4. Consider a release-age gate. npm CLI 11.10.0 added min-release-age, which only installs versions that have been available for more than a given number of days. Most poisoned releases are caught within hours, so even one day of delay buys a lot.
  5. Audit your own workflows for pull_request_target jobs that check out PR code.

Quick hits

  • Hugging Face discloses a breach run by an AI agent (Jul 16). Hugging Face says an intrusion into part of its production infrastructure was "driven, end to end, by an autonomous AI agent system." It says it found no tampering with public models, datasets or Spaces, doesn't yet know which model was behind it, and recommends rotating your access tokens.
  • GPT-5.6 Sol has been deleting files (Jul 16). After users reported lost files and a wiped production database, OpenAI's Codex lead Thibault Sottiaux said the deletions mostly happened in Full-Access mode without sandboxing, and called one an "honest mistake." OpenAI says it's steering users toward safer permission modes and adding safeguards.
  • A record Patch Tuesday (Jul 14). Microsoft's July release is its biggest yet, roughly 570 fixes by most counts (some tallies are higher). Microsoft had warned on July 9 that AI-driven vulnerability discovery means more fixes in every release from here on.

What I'm watching

Whether Hugging Face, or anyone else, identifies whose agent was behind its breach.

Sources

AsyncAPI npm compromise

  • Microsoft Security Blog, analysis of the AsyncAPI npm supply chain compromise (Jul 15, 2026)
  • npm Docs, min-release-age config option
  • Security Affairs, coverage of the AsyncAPI attack (Jul 15, 2026)

Quick hits

  • Hugging Face, security incident disclosure (Jul 16, 2026)
  • OpenAI, GPT-5.6 deployment safety notes
  • The Register, OpenAI on GPT-5.6 file deletions (Jul 16, 2026)
  • Microsoft Security Response Center, July 2026 security update release notes
  • BleepingComputer, Microsoft expects more updates from AI-discovered flaws (Jul 9, 2026)
← Previous

An OpenAI Model Escaped Its Test Sandbox and Hacked Hugging Face

Next →

AI Was Supposed to Kill Dev Jobs. The Postings Went Up.

STAY UPDATED

Get new posts on software engineering and AI in your inbox. No spam, unsubscribe anytime.