MemTensor's Latest Tag Was the Implant. Clean Builds Lasted Minutes.
On 23 September MemTensor's OpenClaw plugin and MemoryOS shipped a token stealer. Clean builds lasted minutes. Pulling the versions did not end the impact clock.
TanStack's May npm worm was pulled in hours. CrowdSec learned in September a stolen CI token had already read private git. Trusted open source is now the door.
Open-source libraries are a threat vector because install runs code on hosts that already hold tokens. TanStack's 11 May npm compromise lasted minutes on the registry and months in victim CI. CrowdSec learned in September that a May token had read private GitHub. Provenance does not close that gap. Scope the token. Hunt the clone.
The part that should bother you is not that TanStack got hit. TanStack is one of the better-run libraries in JavaScript. The part that should bother you is the two clocks.
On 11 May, 84 malicious versions across 42 @tanstack/* packages sat on npm for minutes. An outside researcher filed in 26 minutes. The last tarball was gone the same evening. On 15 May, TanStack posted an all-clear.
On 17 September, CrowdSec confirmed that a May CI token had already read its private GitHub tree. Fuites Infos had called the day before. Four months after the package clock stopped, the impact clock was still running.
That is why open-source projects are a threat vector now. You do not have to get hacked. You have to install a library you already trust, on a runner that can also clone private git. Sometimes it takes months to learn the exploit window was open.
High CVE-2026-45321 Trusted package, install-time theft, months before a victim is told. High because the token outlived the advisory, not because TanStack stayed dirty.
The maintainer page, 15 May. Not a diagram.
The vendor page that closed the other clock, 17 September.
Attackers used to need your network. Then they needed a maintainer password. Now they need a workflow that already publishes for you, and a cache that already trusts a pull request.
Open source concentrates that trust. A popular library is installed by CI, by laptops, and by other libraries. Install is not a download. It is code execution on a host that already holds cloud metadata, GitHub tokens, npm credentials, and SSH keys. TanStack's own advisory says any environment that installed an affected version on 11 May should be treated as compromised.
The economics flipped. One six-minute publish against a loved namespace beats a year of phishing developers one at a time. The worm in this campaign, tracked as Mini Shai-Hulud, was built to steal those credentials and republish from the next maintainer it reached. Mistral's SDK advisory is the hop in the same week. CrowdSec is the hop you heard about in September.
This is not a new class. xz-utils sat in Linux compression until a Microsoft engineer noticed SSH was 500 milliseconds slow. Shai-Hulud ate npm in 2025 by turning stolen tokens into more packages. The 2026 change is that the publish itself can look legitimate. OIDC trusted publishing, 2FA, and SLSA Build Level 3 provenance all held for TanStack. Snyk called it the first npm worm with valid SLSA attestations. The badge said the tarball came from TanStack/router on main. It did.
Nobody phished Tanner Linsley. Nobody stole an npm token. The hardening note is blunt: the project's own pipeline minted the publish credential and handed it over.
Three known classes, chained. A pull_request_target workflow checked out a fork pull request and ran it with base-repo cache write. That is the Pwn Request pattern GitHub's security lab has documented for years. The job poisoned the shared pnpm store under a key the release workflow would later restore. When a legitimate merge to main ran release, attacker binaries were already on disk. They pulled the short-lived OIDC token out of the Actions runner process and posted straight to the registry. The intended Publish Packages step never ran. Tests failed. The malware published anyway.
The first public write-up was issue #7383, opened at 19:46 UTC by ashishkurmi at StepSecurity, 26 minutes after the first publish. Socket called. TanStack deprecated the full 84 versions by 21:03. npm removed tarballs between 22:13 and 23:55. CISA put CVE-2026-45321 on the Known Exploited Vulnerabilities catalog on 27 May, due 10 June. CVSS 9.6.
That is excellent incident response for a package. It is also why people close the ticket.
Downstream is where the months hide. OpenAI said two employee devices were hit. Limited credential material left a subset of repos those people could read, including signing certificates. No customer data, no production, no rewritten software, per OpenAI. The company was already rolling out minimumReleaseAge. The two devices did not have it yet.
Mistral said an affected developer device published broken npm SDK versions and one working PyPI dropper. Hosted services and user data, per Mistral, were out of scope. Investigation closed 14 May.
CrowdSec is the late confirmation. Private SaaS, AWS routines, connectors, automations. Public Security Engine out of scope. No customer data, per the 17 September statement. The likely hop is a TanStack component in May that extracted a CI token with private-repo read. Same class, they said, as Mistral.
Three well-resourced shops. One library. Two of them said so in May. One needed a September phone call.
The package clock is public. Advisories, deprecations, KEV listings, lockfile diffs. You can watch it.
The impact clock is private. A stolen GitHub token does not page you when it clones. A cloud key does not announce that it listed buckets. Session's file-upload network, which this payload used, is end-to-end encrypted. TanStack's postmortem says blocking by IP or domain is the only network mitigation. There is no attacker C2 dashboard for your SOC to stumble on.
That is why the unknown window stretches. You patched. You rotated the npm token you never lost. You did not hunt May clones from the runner that also held contents: read on the private org. CrowdSec's access window was a short stretch in May. The notice was September. Those are different facts.
The harder part, the part TanStack itself called out, is that the project had no internal alerting on its own publishes. Detection was external. Downstream victims had the same shape: they learned from researchers, from journalists, or from a leak market. If your only signal is "a CVE exists," you are reading the package clock.
It is not a reason to stop using TanStack. Query and the rest of the family were never in the 84 versions. Router and Start were cleaned the same night. The current registry, per the 15 May all-clear, is safe to install.
It is not a September intrusion at CrowdSec. September is the notice. May is the access. Do not file a fresh ticket because the headline is new. File the May CI token.
It is not proof that OIDC trusted publishing was a mistake. Long-lived npm tokens on laptops are still worse. TanStack's audit trail existed because publishes were bound to workflow runs. The hole was id-token: write on a runner that also restored an untrusted cache. Endor Labs' write-up is the same sentence: isolate the publish job, or the short-lived token is just a faster way to look official.
It is also not the RubyGems agent flood. Same month, different board. That registry was used as storage. This registry was used as a trusted execution path into other companies.
You will not read every tarball. You can stop treating install as a read-only step.
npm ci or pnpm install should not hold a GitHub token with private-repo read, cloud role credentials, or npm publish rights. CrowdSec's hop was a CI token that could read the private tree from the same place a TanStack install ran. If those are two jobs, a six-minute worm steals a useless identity.ignore-scripts is a blunt control. Native addons that truly need a build can be allowlisted. Everything else is surprise code execution.minimumReleaseAge would have kept the two employee devices off the bad versions. pnpm 11's install cooldown is the same idea. A package that is 20 minutes old is not a package you need tonight.pull_request_target out of CI. If a fork pull request can write a cache key that main will later read, you have already crossed the trust boundary. Pin third-party actions to commit SHAs while you are there.id-token: write on one job, behind an environment approval, with no cache restore and no fork code. Workflow-level write means every step can mint a publish token. That is what "trusted publishing" actually trusts: the runner, not the maintainer.@tanstack/* on 11 May: rotate AWS, GCP, Kubernetes, Vault, GitHub, npm, and SSH material it could reach. Then search that month's CI logs for unexpected clones of private GitHub, and for egress to filev2.getsession.org and the seed*.getsession.org hosts. Four months is long enough for the useful code to move. It is also long enough to miss a second use of the same token..github, a static check such as zizmor on every pull request, and no pull_request_target that checks out the fork. TanStack is adding those because the pattern had been sitting in a working pipeline. Yours is too.The package clock will keep looking fast. Researchers are good at this now. The impact clock is the one that ate CrowdSec's summer. Scope the token so a loved library cannot spend it. Then read May as if someone already cloned you, because in at least one security company's private git, they had.
The registry window is not the incident. The incident is every CI runner and laptop that installed during that window, plus every token those hosts could reach. CrowdSec's private GitHub was read in May and reported in September. OpenAI found two employee devices and had to rotate signing certificates. An all-clear on npm does not tell you whether a stolen token was used.
They did what they are built to do. The malicious versions were published through TanStack's real GitHub Actions OIDC trusted-publisher binding, so the Sigstore attestation was valid. npm audit looks up known CVEs. There was no CVE at 19:20 UTC on 11 May. A clean audit and a green provenance badge are not a statement that the tarball is honest.
No. Mistral's PyPI SDK grew a working import-time dropper in the same campaign. RubyGems spent May as a drop for a different agent flood. xz-utils sat in Linux compression for years before a 500-millisecond SSH delay gave it away. The shared fact is that install and build already run other people's code next to your secrets.
Upgrading closes the package. It does not close a token that already left. Hunt May CI logs for TanStack installs and unexpected private-git clones from those runners. Rotate anything those hosts could reach. Then split install jobs from jobs that hold private-repo read, cloud metadata, or publish rights, and turn off install-time scripts in CI.
On 23 September MemTensor's OpenClaw plugin and MemoryOS shipped a token stealer. Clean builds lasted minutes. Pulling the versions did not end the impact clock.
Accomplish found two Codex sandbox escapes. Heapjack ran host commands from read-only. Overpatch wrote outside the workspace. OpenAI fixed both in eight days.
Hacker News: SafeDep found an npm mathjs clone whose solver unlocks a RAT. JFrog cracked the trigger. The GitHub tree was clean. The tarball was not.