CrowdSec, the French cybersecurity vendor, says attackers made off with about 170 of its private GitHub repositories. The company has since traced the theft back to May 2026’s TanStack npm supply-chain attack.
What makes this one worth sitting with isn’t the exploit itself, but how ordinary the failure underneath it turned out to be, and that’s exactly why the CrowdSec breach is such a good case study for anyone who thinks “we’ll rotate credentials next sprint” is an acceptable answer to a supply-chain compromise.
Quick answer
The CrowdSec breach happened because attackers used a GitHub token stolen from a departed employee’s infected laptop, compromised in May’s TanStack npm attack (CVE-2026-45321), to copy about 170 private CrowdSec repositories on May 22. Nobody caught it. The stolen code didn’t surface until it showed up on a cybercrime forum four months later, on September 16.

What happened in the CrowdSec breach
CrowdSec’s incident report traces everything back to a single stolen credential. Git history places the actual copying in a nine-minute window on May 22, between roughly 05:52 and 06:01 UTC, when an attacker used a GitHub OAuth token belonging to a recently departed employee to pull down about 170 private repositories. That nine-minute window is the entire CrowdSec breach in miniature.
That access should have been closed the day the employee left. Instead, CrowdSec left it open to finish a work handover, and didn’t remove the account until May 25, three days after the repositories were already gone. By then it didn’t matter; the CrowdSec breach had already happened.
Here’s the part that actually bothers me: it’s not the nine minutes of copying that’s the real failure, it’s the four months nobody noticed. The stolen code sat quietly until it turned up on a cybercrime forum on September 16, and the CrowdSec breach became public knowledge a couple of days later.
GitHub’s own support team had to dig up activity logs for that two-hour window before CrowdSec could even confirm the copying was tied to the former employee and the TanStack attack. Investigators also found a geographic fingerprint in the metadata: the access traced to an IP in Toronto, on a system clock set to UTC-4.

The root cause: CVE-2026-45321 and the TanStack attack chain behind the CrowdSec breach
The CrowdSec breach didn’t start at CrowdSec. It started with TanStack, the open-source project, getting hit at the ecosystem level in a compromise now tracked as CVE-2026-45321. On May 11, over about six minutes, an attacker pushed 84 malicious versions across 42 different @tanstack/* npm packages.
The unnerving part is that these went out through TanStack’s own legitimate, trusted publishing pipeline. Nobody had to break the workflow to abuse it.
The attacker got there by chaining three separate weaknesses, not exploiting one big flaw: a misconfigured pull_request_target workflow (the kind of thing security folks call a “Pwn Request”), cache poisoning across the trust boundary between forked and base repositories in GitHub Actions, and pulling an OpenID Connect token straight out of a runner’s memory while it was still live. String those together and you can publish credential-stealing malware under someone else’s trusted identity.
CISA rates this about as seriously as a vulnerability gets: a 9.6 CVSS score, added to the Known Exploited Vulnerabilities catalog on May 27 once active exploitation was confirmed. The malware itself wasn’t picky.
Anyone who installed a bad version risked losing GitHub tokens, npm credentials, cloud credentials, Kubernetes and Vault secrets, and SSH keys, all quietly pulled off the machine. Researchers now attribute the campaign to a group tracked as TeamPCP, also called UNC6780, running malware known in the community as Shai Hulud.
How the stolen token led to the CrowdSec breach
The connection at the heart of the CrowdSec breach is almost embarrassingly simple. A CrowdSec employee’s laptop caught the TanStack malware before that employee left the company. CrowdSec’s own account of the incident is honest about this being two failures stacked on top of each other, not one: an infected laptop handed over a valid credential, and separately, that credential still had live access to repositories it had no business touching anymore. Fix either one on its own and the damage shrinks a lot. Leave both, and an attacker gets three days of unsupervised access to 170 private repos.
What the CrowdSec breach exposed
The archive that eventually leaked was not small. It included CrowdSec’s SaaS console source, internal data-science scripts and models, deployment and automation tooling, and, a little ironically for a company that runs a crowdsourced IP-reputation service, the consensus algorithm it uses to decide which IPs land on its blocklists.
More than 130 of the roughly 170 copied repos were already public, so the private exposure is real but smaller than the “170 repositories” headline makes it sound. Still, that’s the core of what the CrowdSec breach actually cost the company in code.
There was also personal data in the mix: email addresses for 83 CrowdSec users (under 0.05% of its roughly 150,000-user base), plus names, emails, and investment details for 51 people who’d been potential investors back in 2020.
One live credential turned up in the leak, an AWS SNS credential scoped tightly to a notification function. CrowdSec says someone tried using it on August 17 and got nowhere beyond that narrow permission. Everything else in the archive had apparently already been rotated or expired by the time the CrowdSec breach became public.
What the CrowdSec breach didn’t touch
CrowdSec has been pretty specific about the boundaries here. Production infrastructure and databases were never accessed, no source code or CI/CD pipeline was modified, and the compromised account only ever ran fetch and clone operations, never pushes, never privilege escalation.
Once the CrowdSec breach went public, CrowdSec rotated everything that could plausibly have been exposed, and it’s publicly thanked GitHub, GitGuardian, Aikido, and the threat-intel outlet Fuites Info for helping piece the incident together.
CyberInfos analyst take
This section is our read on the situation, not a new factual claim.
The exploit chain here is legitimately clever. The failure that caused the CrowdSec breach is not. TanStack’s malware went after credentials on thousands of machines indiscriminately; this particular token mattered only because it stayed valid on a repository the attacker wanted, days after the person who owned it had already walked out the door.
That’s the mistake worth sitting with: “the employee left” and “the employee’s access is gone” are not the same event, and treating them as interchangeable is how this kind of thing happens.
During an active supply-chain compromise, every live token on every developer machine is a risk the second the malicious package runs. A token that should have died on someone’s last day but didn’t is, in practice, no different from one nobody ever bothered to kill.
There’s also a detection problem worth naming for SOC folks: this is hard to catch in the moment, not with hindsight. A valid OAuth token doing a routine git fetch doesn’t trip most SIEM rules built around failed logins or privilege escalation. It just looks like a token doing its job. That’s the whole reason the CrowdSec breach sat undiscovered for four months.

Supply-chain stats worth knowing
The CrowdSec breach is one data point in a category that keeps getting bigger, and the numbers back that up. Sonatype’s 2026 State of the Software Supply Chain Report counted more than 454,600 newly discovered malicious open-source packages in 2025. That’s a 75% jump from the year before, and it pushed the running total past 1.23 million. Over 99% of that malware lives on npm specifically.
The cost side is brutal. IBM’s Cost of a Data Breach research puts the average supply-chain compromise at about $4.91 million and 267 days to fully resolve, longer than any other breach category it tracks. Verizon’s 2025 DBIR found third-party involvement in breaches doubled year over year, from around 15% to 30%.
May 2026, the same month TanStack got hit, was rough industry-wide. One analysis found a single coordinated campaign hit more than 170 npm packages and two PyPI packages within 48 hours. That included TanStack’s own react-router package (3 million-plus weekly downloads) and Mistral AI’s official SDK.
Why credential rotation isn’t optional
If there’s one practical takeaway from the CrowdSec breach for developers, DevOps engineers, and open-source maintainers, it’s this: once a supply-chain compromise is confirmed, every credential reachable from an affected machine is burned. Rotating it next sprint isn’t rotation, it’s a formality after the fact.
The official remediation guidance for CVE-2026-45321 doesn’t hedge on this: rotate every potentially exposed credential, GitHub tokens, cloud credentials, SSH keys, Kubernetes secrets, npm credentials, on any system that ever installed one of the bad package versions. Clear local package-manager caches entirely, and check lockfiles for the malicious versions or for Git-based dependencies that shouldn’t be there.
The CrowdSec breach makes the speed argument better than any advisory could. The credential that got misused wasn’t a fresh secret, it belonged to an account that should already have been dead. If access revocation had happened on the employee’s actual last day instead of three days later, the token used on May 22 wouldn’t have worked. Rotation that arrives a few days late is, functionally, rotation that didn’t happen in time.
On the CI/CD side, the fix is structural, not just a credential-hygiene checklist: stop using pull_request_target against untrusted fork code, keep id-token: write permissions as narrow as the workflow allows, and separate build caches for trusted and untrusted (fork-triggered) runs so a poisoned cache can’t cross over.

Checklist for developers and DevOps teams
- Rotate GitHub tokens, npm tokens, SSH keys, cloud credentials, and Kubernetes/Vault secrets on any machine that installed an affected @tanstack/* package between May 11–22, 2026.
- Audit everything a departing employee’s account could reach, and cut access on their actual last day, not after a grace period.
- Check GitHub Actions workflows for
pull_request_targetagainst untrusted fork code, and tightenid-token: writepermissions to the bare minimum. - Keep build caches separate between trusted and untrusted (fork) workflow runs.
- Clear local npm/package-manager caches and check lockfiles for the known-bad @tanstack/* versions.
- Turn on npm two-factor auth for publishing, and provenance attestation for anything you publish yourself.
- Build alerting for “valid token doing routine Git activity from a dormant or offboarded account,” not just failed logins.
- If you run a SaaS product, actually verify whether production, databases, and CI/CD were touched, don’t just assume a repo breach stops at the repo.
FAQ
What is the CrowdSec breach?
The theft of roughly 170 private GitHub repositories from CrowdSec, using a GitHub token stolen during May 2026’s TanStack npm attack. The stolen code surfaced publicly on September 16, 2026.
Was CrowdSec’s production infrastructure affected?
No. As part of the CrowdSec breach, production systems and databases weren’t accessed, and no code or CI/CD pipeline was changed. The compromised account only fetched and cloned repositories.
Who’s behind the TanStack attack?
Researchers point to a group tracked as TeamPCP, also known as UNC6780, using malware referred to as Shai Hulud.
What should developers do after a supply-chain attack like this?
Rotate every credential on any machine that installed an affected package, immediately, rather than waiting on a formal incident report.
Final Thoughts
Strip away the technical detail and the CrowdSec breach is a story about timing, not skill. A supply-chain worm infected a laptop and stole a token. An offboarding gap kept that token alive three days longer than it should have been. Four months of silence let the theft sit until the attacker decided to cash it in.
None of those three steps needed to be clever on their own. Together, they cost a cybersecurity company 170 repositories.
If your team touched an affected @tanstack/* package, the move is simple: rotate everything on every exposed machine now, and don’t let “we’ll get to access revocation later” survive an active incident like the CrowdSec breach.
Past that, it’s structural work, tighter GitHub Actions trust boundaries, same-day offboarding, and alerting that treats a valid token behaving normally from a dormant account as worth a second look.
