Download the latest Vulnerability & Exploitation Report

Download now

TanStack Supply Chain Attack Analysis

Context

Every hack happens in a context where humans, business, technology, or society as a whole is evolving. What stings for CrowdSec is that many of us come from red-team pentesting backgrounds, have worked in cyber for decades, and have adopted a “cybersec” muscle memory in our daily work. So being caught leaking code is painful. 

CrowdSec is doing much better after we found deeper PMF (Product-Market Fit) for our data, and our low-touch SaaS model started to click with users. The team is a bit smaller because we had to keep costs under control in an environment where access to funds was more limited than before. Overall, we were a happy startup sailing toward break-even. We started discussing with governments and ministries in at least 7 countries. An industry AAA profile was knocking at the door; all was for the best until… September 16th happened and took us by surprise.

Now, what happened, how, what was the team’s reaction, the timeline, the origin point, how to react if something similar happens to your team, and what will we do differently? What is the real impact beyond the big news title? What’s important, marginal, or objectively meaningless?

But first things first… What happened?

The Timeline

  • May 11th, 2026: TeamPCP compromises a famous NPM package repository named TanStack, widely used by developers to create Node-based web UI. 42 packages are backdoored with their malware “Shai Hulud”, specialized in credentials and token harvesting.
  • May 22nd, 2026: TeamPCP (Threat Actor UNC6780) claimed responsibility for the hack of some Mistral AI repositories.
  • May 22nd, 2026 – 05:52:29 until 06:01:33 UTC: one of the founders of BreachForum and a member, diencracked <diencracked@cock.li> downloaded the content of ~170 private CrowdSec GitHub repositories from an IP address in Toronto, Canada, with a computer Timezone set to UTC-4. At least that’s what the Git data shows. The number of repositories is relatively irrelevant, as is their absolute size, since they speak more to code organization and images used in the Web interface than anything else. But on breach forums, numbers are the name of the game. The key point is that he had access to a private codebase that wasn’t supposed to be exposed, and that’s a fact.
  • May 25th, 2026 – afternoon: Compromised employee’s laptop GitHub access is revoked (all others were already). We kept them alive because we parted on good terms with our developer, and he wanted to finalize some work.  
  • Aug 17th, 2026: The AWS token used for SNS notifications is tested to see its precise authorizations
  • Sept 16th, 2026 – 17h45: Publication on the forum
  • Sept 16th, 2026 – 20h: contact between our team and the Fuites Info staff; crisis cell is put together
  • Sept 16th, 2026 – night: initial forensic actions, key credential and token rotation
  • Sept 17th, 2026 – morning: forensic, coordination, reporting, remaining token/credentials rotation
  • Sept 17th, 2026 – noon: initial PR explaining the facts we are already sure about
  • Sept 17th, 2026 – 18h: GitHub to the rescue; they helped us identify the full story behind the token (the famous API key MrWHO talked about in the forum).
  • Sept 18th, 2026: Wrap-up of the incident, release of this full final report.

Risk assessment

In any leak context, you’re always pressed to identify whether only the codebase was affected or whether connected data and cloud infrastructure were also affected. In “theory”, the ideal cybersecurity scenario is that authentication mechanisms, tokens, identities, and any form of credentials are absolutely absent from any codebase. Still, we don’t live in this beautiful “theory” world; we live on Earth, with humans.

So the first step is to make sure that anything that has leaked doesn’t contain any “credentials” (in its larger acceptation), any sensitive data, and if that’s the case, that those are deprecated (in our lingo, “rotated” to indicate they are not usable any longer).

Code

  • Console: For the record, we thought a lot of time about open-sourcing the Console itself but didn’t do it (yet) for three main reasons.
    • 1/ It’s not something you can use without the AWS infrastructure and microservices running behind it.
    • 2/ Structurally, it’s not really a project where users can propose PR/MR or contribute; it’s actually easier to ask for a feature than add it yourself
    • 3/The code being open-sourced is always deliberately planned this way.
      While it’s doable to open source something that wasn’t intended to be, fast-moving codebases (like the SaaS console) aren’t ideal candidates. Code quality isn’t the issue here; it’s that no one would care about it or replicate it at home. Now, does it have value? Yes, the time our team spent coding it. Is it valuable to someone else? We can confidently say not really; it’s far too contextual. Did it contain secrets? No. Maybe the codebase wouldn’t yet fully meet our open-sourcing standards, but that would be it. Can it lead to a security concern is the real question. Security by obscurity is never a good model; having the full source code in hand can eventually fast-track research into potential weaknesses, specifically in the AI-everything timeline. Now we do have access to those AIs too and can (and do) assess our source code security as well. So is it ideal? No. Is it very bad? No. We’ll still monitor tightly the various log sources, trails, and audits we have and check that nothing deviates from normal. Anyway, this codebase is changing extremely fast, and 4 months down the road, it’s already meaningfully different from what was released.
  • Data processing: Some data science scripts and models were part of the leak. Not ideal either, but honestly, without the data to train those models or feed those scripts, they have little value. The “Consensus Algorithm” was also part of the leak, but we already explained very transparently how it’s globally architected; we thought more than once about open-sourcing it, but for the same reasons stated above, we didn’t. Can the Consensus (the algorithm adding IP addresses to blocklists) be poisoned, compromised, or not? Well, to the best of our knowledge and understanding of our own system, no. The algorithm requires tens of sightings coming from at least tens of vetted security engines spread across tens of different Autonomous Systems. What isn’t public was mostly the thresholds we set for diversity and number of detections; still, those are moving targets. It would require a motivated attacker to spend an immense amount of money to instantiate enough servers to influence the network into banning a non-offending IP. The difference is that before this leak, the attacker wouldn’t know exactly how many; now, thresholds are known. Fine, we can adjust those thresholds (like we frequently do) and be very vigilant about discrepancies. Now the network effect and its sheer size make statistical variations very visible on our radar since the “mean” is very solid. 
  • Various automation scripts: That covers many different scripts. Slack bot automations to report, some sites to publish news or content, deployment scripts for test purposes, QC, QA, etc. It would be extremely boring to go through the details. <TL/DR> no value, no risk for users, clients, or network, or data integrity.

Credentials: We were very close to clean. The useful “credential” leaked was a token to use an AWS service called SNS, and it was properly scoped (in our lingo, limited to just this), so it was “live” but not usable for anything beyond basic notifications. A few other tokens were either already rotated or not usable from the Internet, to our current knowledge.

Data: This is not only critical for clients’ safety but also reprehensible under the GDPR framework. There was no clients’ or partners’ information in the leak, except for a few email addresses used specifically by our Data Science team to monitor project usage, users’ reactions to a new feature, and overall statistical reasons. Not many compared to ~150K users: 83 (<0.05%), mostly Gmails. We’ll reach out to those users to explain the situation, but nothing in this can weaken their security posture except cybercriminals knowing they run CrowdSec. We also inadvertently disclosed the first/last names of 51 potential investors from 2020, their email addresses, and investment context, which we will report to them and the proper authorities.

What are the impacts?

As CEO, I have to evaluate the full scope, and it’s more complex than the headline news shows.

The first thing that popped into my head is, “It’s really unfair; we couldn’t do much about it, and it’ll have a negative impact on us.” The reality looks fairly different 48 hours later. First, I was astonished by how comprehensive and genuinely benevolent our team, clients, partners, and providers were. 

If anything, we’ve mostly received love and support from our community, partners, and VC alike. Aikido, Fuites Info, and GitGuardian offered their support, and GitHub staff were very helpful. Some clients asked legitimate questions but mostly understood the posture, appreciated the professionalism and transparency, and patiently waited for factual answers rather than hasty ones.

And… Our team. This tango where everyone knew what to do, how, synchronized, thoroughly searched, inspected, introspected, and asked painful questions was genuinely a blast. Being a CEO is often a lonely place, but feeling all those professionals building a professional response together at such a fast pace was a moment of pride. As for my beloved network of LinkedIn professionals, alumni, and friends, you know who you are; thanks a lot for the kind words. Last but not least, you don’t organize such an intense effort and carry it through the finish line.

Of course, some asked, “They claim to know who attacks us but cannot avoid them attacking themselves”, while others sent passive-aggressive crying smileys, but an overwhelming part of the security professional community was supportive and understanding.

Never let a good crisis go to waste. We’ve improved our reaction time: 48h to cover the full inventory, token rotation, forensic, and PR operation isn’t bad timing per se, but if we ever face another crisis, we can probably pack this timeline in under 24h. Now, preventing any other crisis from happening, specifically Supply Chain attacks, is the real challenge here.

But I won’t dodge the question, and I owe you an answer on “how bad is it.” Simple answer: it’s a strong stress test for our distributed, crowdsourced network system. By design, it should be resilient to this type of event, but now it’s being battle-tested. To the best of our knowledge, strict privilege separation, scoped AWS tokens, and prompt revocation of the departed employee’s core access meant the attacker hit a dead end. Security experts won’t mind because they understand we didn’t fail our mission or cut corners on security. Clients may wonder what happened, but we can explain it in layman’s terms. Prospects may be spooked, but we sell a fairly technical product, so most will understand once we explain the situation. Not ideal, obviously, but not fatal by a long shot. 

But the ones we’re most genuinely sorry for are our early investors, whether potential or those who took the move. Leaking your names and email addresses is an issue we’ll discuss directly with you and the competent authorities, and for this I personally apologize. The system that, back then in 2020, made interactions with us easier was never intended to be public.

Anyone who suffered an issue like this is less likely to face it again because of the pain it caused, so if anything, we walk out stronger and sharper from this crisis than before, with a brand and ego wound, the latter being irrelevant in the grand scheme of things. Overall, it seems CrowdSec isn’t just a network effect, but a real community of supportive professionals, which is heartwarming. 

How it happened exactly

On the 16th of September, a user published on pwnforum an archive containing source code from the CrowdSec GitHub organization, as relayed by https://fuitesinfos.fr/article/2026-09-16-crowdsec

Timeboxing the facts: once Christophe from Fuites Info gave us the information and archive, we could see that the archive contained crowdsec-ghsa-273h-gvwr-c3qj, a repository that was destroyed on May 27th. The latest commit present across all repositories is from May 22, 2026 01:24 UTC, and the archive timestamp is set to May 22; this lines up.

At that point, we know with a high degree of certainty that the leak is limited to CrowdSecurity’s source code, including 130+ public repositories and many private ones. CrowdSec’s infrastructure or databases have not been accessed or compromised. No code was altered, whether in the open-source software, our private source code, or the build pipelines.

Our infrastructure is AWS serverless, and we make heavy use of SSM/Secrets Manager, so the number of credentials present is very low but still warrants analysis. Most of the tokens and secrets present in the source code had been revoked or rotated before the leak, but we can see that the ones present and usable have been probed:

For example, the dump included an AWS secret assertible-zapier-sns-sender, and someone tried to use it on 17 August 2026 from IP 23.234.84.102 to perform GetCallerIdentity and ListTopics on both dev and env topics. This AWS role was restricted to publishing on a single SNS topic; it didn’t go any further.

The archive .github/.git/config contains the origin that was used to clone the repositories:

...
[remote "origin"]
	url = https://oauth2:gho_xxxxxxxxx@github.com/crowdsecurity/.github.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	remote = origin
	merge = refs/heads/main

This tells us the token used to clone the repositories is an OAuth token (gho_xxx), and the likelihood is higher because its checksum is correct [2]. The methodology is well aligned with the TeamPCP / Mini Shai-Hulud tactics.

However, we couldn’t find any trace of this OAuth token in our organization’s audit log or in any of the current GitHub organization members’ audit logs. You can download those from the web UI and look for the token’s hashed version (echo -n $token | openssl dgst -sha256 -binary | base64). This was a dead end.

We also reviewed the list of active OAuth integrations in the organization (in “Access Restricted” mode) but didn’t find anything suspicious either; none of the integrations suffered public breaches in the relevant timeframe.

If it was an active user’s OAuth token, we would expect to see related activity in the activity log. On the other hand, GitHub’s audit log only tracks specific actions [2.1], and only enterprise plans (which we’re not on) keep git activity on a rolling 7-day window.

[2] https://github.blog/engineering/platform-security/behind-githubs-new-authentication-token-formats/

[2.1] https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/reviewing-the-audit-log-for-your-organization

The real complexity behind this forensic analysis is that the token used to download the private repositories no longer existed when we became aware of the code leak. So it was created, lived, and died without leaving us any traces beyond its usage. This is where GitHub’s professional support was invaluable. They traced the token’s full lifecycle and confirmed our initial suspicions about TanStack.

At that point, our main concern was that we still didn’t know the origin of the compromise. We checked for user tokens and scanned for malicious packages, VS Code extensions, etc. The developer machines came back clean.

We promptly investigated our own repositories’ Git history to see if some of the backdoored packages touched our repositories at some point, but this was inconclusive. While some TanStack packages were present, none were on the backdoored list. Finally, we enforce a minimum age on Node packages. 

One thing that puzzled us was that TeamPCP is known to not restrict itself to GitHub credentials, but also to look for other tokens such as AWS credentials, SSH keys, etc. While GitHub gives you very little visibility into git activity, we have good visibility and alerting on AWS, and nothing suspicious has happened since the supply chain attacks or since the credentials in the leak were probed.

With the OAuth token and a precise timeframe for the activity, we reached out to GitHub support to see if we could get more information. They kindly provided the Git activity within the 2-hour timeframe of the dump. We then discovered that it was an employee who had just left the company, but that was still part of the GitHub organization for legitimate reasons, and his account was used to dump the repositories:

2026-05-22 05:52:32.138 UTC – fetch – crowdsecurity/XYX – <redacted> – 178.249.214.XX

Based on the git information in the leaked archive, the IP is in Toronto, Canada, in the UTC -4 time zone. The ex-employee got compromised by the TanStack supply chain attack, matching the methodology. We removed his account from the GitHub organization on 25 May 2026, 3 days after the incident.

This also explains why we didn’t see AWS or infrastructure-related activity, as we had already revoked the employee’s access.

After identifying the root cause and further auditing the user’s Git activity and existing accounts, we confirmed that his account was used solely to perform the Git clones that led to the leak. No commit, no changes to the code, the infrastructure, or the CI was performed. 

What action we took to avoid any further incident

We had a lot of security mechanisms and procedures in place prior to this incident:

  • Strict privilege separation (for example, as a CEO, I don’t have any access to bank accounts, organization admin tools, AWS console, etc., and this is best practice and applied to everyone, everywhere)
  • Tight scoping: What applies to user rights equally applies to apps, AIs, cloud routines, and scripts, to avoid granting any right beyond what is strictly needed to fulfill their role.
  • 2FA everywhere, for every tool and everyone, along with passkeys and physical (Titan Key) devices
  • Password wallets: obvious, but security should always be explicit
  • Safety sentences: if a key member of the organization with extended rights is physically compromised (or his family), we have agreed on specific words to drop in the conversation to alert our interlocutor we are compromised.
  • Audits: whether internal, AI-led, or external, they became a routine. 
  • Logs everywhere: During this crisis, we learned we want deeper logging of actions on GitHub, but the logs from our toolchains, CI/CD components, and AWS trails were very solid. Having traces allows us to trace but also to react early, and after all, we are CrowdSec, so pretty privy to the issue 🙂
  • Pentesting: We come from this background, and we know how to value these. How frequently to run them, what form they should take- this all changes over time, but testing the company employees and our source code is part of what we do.
  • NPM node age monitoring: to make sure we are not running on a version that is too recent to be audited or too old to carry security risk.
  • Onboarding/deboarding procedures: The full lifecycle of an employee’s credentials matters, and removing (or knowing why you kept) all access once they are gone matters even more.
  • Automated code analysis: Every commit is automatically scanned for potential vulnerabilities or logic flaws
  • Publication, QA & QC procedures & reviews: whether automated or manual, these are classical components of an editor’s tool belt
  • And much more…

Yet, all of this couldn’t prevent a Supply Chain Attack, so what could have?

EDRs: At the time of the incident, we didn’t enforce EDR on developers’ machines, but we’ve since started using endpoint protection that actively focuses on malicious packages, extensions, etc. As supply chain attacks become the new plague and virtually anyone can get caught in them, we should have done this earlier. 

The workstations/laptops of people interacting with our codebase or infrastructure now run EDRs (the Aikido Security one) to reduce the risk of supply-chain attacks, but in-memory analysis and runtime monitoring with something like CrowdStrike’s EDR could further close the gap. However, because the employee had already left the company, the likelihood that he still had endpoint protection on his machine was low.

WRITTEN BY

You may also like

CrowdSec Statement: Source Code Exposure in May 2026
Announcement

CrowdSec Statement: Source Code Exposure in May 2026

On September 16, CrowdSec was informed of a source code leak involving our GitHub repository, which occurred in May 2026. Our team verified and confirmed the report. CrowdSec source code consists of two parts: a private one and another that hosts our Free Open Source Software (i.e., the Security Engine), which is public by design […]

live exploit tracker
Announcement

Introducing Live Exploit Tracker: Know What’s Exploited, Act Faster

See which CVEs are actively exploited in the wild. Live Exploit Tracker helps you prioritize faster using real attack activity, IPs, and IoCs.

Protecting CAPI reliability: Introducing rate limiting on CrowdSec’s Central API
Announcement

Protecting CAPI reliability: Introducing rate limiting on CrowdSec’s Central API

To keep CrowdSec’s Central API (CAPI) reliable as usage continues to grow, we’ve introduced rate limiting. This change helps prevent misconfigured or broken deployments from generating excessive traffic, ensuring fair access and consistent performance for everyone.