A supply chain attack on Tanstack packages (May 2026) exploited GitHub Actions' 'pull request target' trigger combined with cache poisoning to inject malicious code into npm packages like React Router and React Query, which have millions of weekly downloads; the attack demonstrates that developers must version-lock packages, use minimum release age features, and avoid workflows that execute pull request code with secrets to prevent similar compromises.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
React Router Got Hacked!Added:
If you missed out the news, let me tell you that tanstack very popular collection of packages. We have used react router. We have used tanstack table. There's a whole JavaScript framework that you can use which is tan stack start. A lot of these packages have been compromised in today's hack.
Now this is something that I have very recently created a video on when bid warden's CLI package also was hacked and now the same thing has happened with tanstack which is tanstack npm package is compromised inside mini shy hulude supply chain attack. We have been seeing a lot of these attacks in the last few weeks and months and I am just honestly tired at this point to be honest because this is this is something that is you can't do anything as an individual right to prevent these attacks from happening.
What you can do is what we have always talked about is version locking your packages properly and using a minimum release age version feature of your package managers so that you do not install anything new and latest at least for a few days of time like 6 to 7 days.
So look at this. On May 11th, 2026, between 1920 and 1926, 84 malicious npm packages were published across 42 packages in Tanstack namespace. And this is the same namespace that also hosts things like React Query. Look at this.
Tanstack ReactQuery has a mindbogling 54 million downloads every single week, which is an insane number of people and Asians using this technology. And thinking that something like this can be compromised actually absurd. The packages were not published by an attacker who stole credentials. They were published by Tanstack's legitimate release pipeline using its trusted OIDC identity. After attacker controlled code hijacked the runner mid work, the malicious version spread to Mistral AI UiPath and dozens of other maintainers within hours. So this was not just limited to Tanstack, but I do feel like probably one of the biggest impact to web developers comes from this packet.
Nanstack React Router alone receives over 12.7 million weekly downloads which is obviously less than 54 million downloads of React query which is I would say the most popular package out there. So again, if your team has installed any effect and stack versions, treat the install environment as compromised and rotate every secret available in that host. And this is bad, right? Because this is um basically you in simple words this just means that if you have installed this malicious version this means that you have downloaded a malware which is running as root access or whatever your CI code is generally running as and it has access to everything all the files all the environment variables every single trusted thing that you inject inside a CI environmentally core tanstack router family was the initial victor but the W's self-propagation mechanism rapidly expanded its blast radius these are the list of packages and the versions which were compromised including react router, view router, you know, a bunch of routers here, a bunch of query packages, tables, forms, virtual and store. And then apparently some of other packages also got infected. This Mistral AI, UiPath, Quark and some other completely unrelated packages, right? I've not heard about these ones. So again, this is not a new category of attack. I have actually discussed in detail on how, you know, an attack like this is carried out in one of my last videos. I will link it somewhere here. You can check it out.
It's pretty similar to that attack in that regards. But still, let me actually just pull up whiteboard and explain to you how this specific attack was carried out. So let's try to understand how this works. So it starts again with GitHub actions like usual. And in GitHub actions there are basically two ways to trigger a work. First is like on pull request you know on pull request when a pull request is opened and the second action which is there is on pull request target. Now see in GitHub you know a lot of open source projects exist right? For example, let's say we take example of this tanstack thing only. Let's say tan tanstack/ start. Let's as an example, somebody came in and said that okay, I want to add a feature and they forged it. For example, let's say I forged it at mayhole mpd/start as one of my GitHub repos, right? And then what I did is that I created that feature whatever I wanted feature and I opened a pull request right to the original repository. Now this is where on pull request and on pull request target comes into play. So if tanstack start repository has configured on pull request what's going to happen is that when I create this pull request and when the CI runs you know those continuous integration actions that are there that are defined in this YAML files and GitHub folder when they will run what's going to happen is that if it is pull request this one which is the safer one so I'm going to label this as green if this is pull request when it runs the CI on my branch you know on on this thing the pull request that I have opened pull request will not run it with secrets of original repo right imagine that there is some you know it's not there but let's imagine that there is something right like a token or something inside the secrets over here so whenever the actual maintainers of tanstack are creating a PR and they are you know pushing it over as an official pull request inside the repo itself that would still run with all the tokens and everything because they are obviously creating it on the repo itself but if I am contributing an external pull request this would not trigger if you're on pull request however if you have this on pull request target. This is where the problem is and this is how tanstack also got compromised. Now the problem is that if your GitHub action for example let's say you have bunch of these actions over here you know action one.yaml action 2.yaml and so on and so forth. If any one of them has actually on pull request target as a trigger, what's going to happen is that when you create and open a pull request, even the external one, it's going to run with all the secrets first of all and it's going to run the master branch code, right? And it's also going to use the workflows from the master branch, right? So, it's not going to use your workflows that you have created a, you know, as a as a pull request. Obviously, you can't just, you know, change the workflow file itself, send a pull request and that m that workflow would automatically run. But still it would run all the secrets.
It'll run the master branch code and it'll run the workflows which are also in the master branch. Now I mean technically speaking if you look at this this actually itself is not a vulnerability in it because look at this you do have secrets. Yes you do run the workflow yes with secrets but in no step you are actually configuring to run the pull request code itself. So the code that this feature for example this is a malicious feature or whatever. If this features code is not getting executed in the pull request over here which is running with pull request target action then this is basically safe right because you are running inside your own CI runners with your own secrets and the code that is getting getting checked out is the master branch code not code which pull request came in that is also why it says like you know pull request target because it's start it's actually going to run code and the stuff on the target branch right that target of the pull that you're now obviously the problem is that this is only safe if you Never touch the pull request code. Right? That is the contract that you have to abide by if you want to use pull request target because the moment you start touching pull request code itself inside the workflow action then it can be manipulated. Right? Then you can run arbitrary code inside a workflow triggered by somebody else external using all the secrets that are available. Now look at this. Inside of tanstack there was a workflow called bundle size.yaml which used this exact pull request target trigger. But it checked out the fork's merge ref and execute fork controlled code which is actually wrong right you're not supposed to I mean in this case from a feature point of view this is right but because you are using pull request target this is also pulling in actual real secrets of that specific rep even if somebody third party is contributing that pull request target over here and over here you are manually checking out pull request itself which was open so we are forking the code and then you are calling cache action and then you are running the code. Now see technically speaking because you can run pull request code itself it's possible to compromise this environment right here right then and there right but the attacker in our case was actually smart because they did not do that they actually did a second step step two which was cash poison and this is actually important and this also links to previous video that I actually did now step one was this you know the whole thing that I explained you step two was cash poisoning and the reason I'll tell you why this is the case before that the reason the attacker did not actually did arbitrary code execution right away even if that they could is because the best they would have gotten from an open source project like you know panstack would be like a GitHub token and maybe a few more secrets and the bundle size.yamel workflow that that was there this actually did not give a GitHub token or any sort of secret that can be used to publish the npm package version even if you compromise this specific workflow which was bundle size.yaml YAML even if the attacker was successfully able to compromise it. The automatically injected GitHub tokens and the other secrets which existed they were insufficient for the attacker publish a new version and there is basically no benefit as such to just compromise a single VM when you can publish a package to tens of millions of people just like I showed you and let all the computers across the world install that malware.
Right? So that is why step two was necessary and you could not just arbitrary execute the code because even if you could you would not get authenticated tokens to do this final attack thing which is important. Now here's the fun part how the cache poisoning attack work. See we have seen that bundle size.yamel does not has permission to publish any packages or do anything interesting right? So what we need to do is we need to I mean when I say v I mean attacker needs to run code the arbitrary code in release.yamel YAML file which is a different YAML configuration that runs on master branch and this has permission to publish the package. Right now how do you run some arbitrary code inside this file without actually touching any sort of you know creating any sort of PR or anything because obviously no maintainer will merge a modified file or anything right and that is where cache poisoning comes into play because what happens is that this bundle size.yaml YAML is also doing a bunch of stuff for example in in installing packages right as one of the first steps and this package installation is most of the times cached for speed reason right because you know like pnpm install is extremely slow if you're doing it for the first time as a matter of fact everything is slow right except for I think bun or something but most of these platforms like GitHub actions provide you for the ability to cache the result of these installations and a lot of other things you can use like caching arbitrarily with whatever action but the core idea is that caching uses key identifier. So what this means is that cache will say that okay for this specific key let's say XY Z 1 2 3 I want to store this specific file let's say a 1GB file whatever and if this key changes at the time when the action is running then file would not get downloaded if the key is still the same then the file would get downloaded. A simple example of this is let's say if you have a PNPM lock file right let's say you have this file and you take an MD5 hash of this and if this value comes out to be like certain string over here if this string matches the cache if there's a cache head you can just download the same 1GB node modules right you don't have to actually go ahead and install it uhly you can just reuse or you know copy the local node modules and it'll speed up your installation but if your MD5 is different then the value will change and you would not get a cache. Now what attacker did basically is that they kept pnpm lock.l file. This is exactly what tanstack was also using in one of the release.yamel. The simpler idea is I don't want to get into very s small details but the simpler idea is pnpm lock was used as one of the cache keys which resulted in a cache which was hit and the node modules were downloaded but this cache was modified by this specific runner over here. Right?
Because this bundle size.yamel YAML was also using the same cache key to upsert date the cache value against a specific value. So they were able to premp compute this key this final key which would be there. It was not MD5. I'm just giving you an example here. It was something like Linux and some some prefixes over here which you can read in the blog post. But the idea is that they very smartly did not change PNPM lock file. They just sent a pull request to trigger this action under pull request target over here which we just saw over here which ran into main repos context did the cache poisoning and when the next time this release.yamel YAML when this was organically ran ran normally like by an author or a maintainer nobody knew that they have actually downloaded a node module which is actually a virus right over here which includes this hack or this ability to do post install scripts and you know just doing a bunch of things which would steal the right token to publish on npm package manager right so once you have that ability to publish it on npm of course then now you can create a release and just publish it so that's it is when once you know the attacker has successfully executed its own code in this release.yml workflow because of cache poisoning then this router init.js JS this 2.3 MB file was smuggled into the compromised star balls route file not declared in packages files field which proves the tab wall was tampered with the outside normal build process right so the attacker was able to inject their code run it exit one the optional dependency fails gracefully leaving almost no trace and install logs while the payload is already executed in the background so now this this itself is you know offiscated JavaScript code the core idea is that now you are actually executing something inside a machine that has access to a lot of damaging secrets. One of them being the ability to install um publish an npm package. And the way this attack, the way this virus works is just fickle, right? So it'll try to steal everything AWS credentials, hashikor, vault, kubernetus, workstation targets and it'll try to you know exfiltrate all the data once it has infected your computers, right? So that is what we are talking about. So I mean realistically speaking we have companies like snake and like other security companies which are monitoring these new packages releases almost instantly right so that is like a good thing that why we how we are able to catch these things within a few hours of time otherwise that will have a catastrophic disaster on community as a whole right because it's very easy to spread this virus to tens of millions of computers running globally maybe like in a week's time as we have seen but the core idea for you guys is that if you want to be save this is first things a few things first of all version lock your packages I keep screaming about this in basically every video on similar topic um that version locking means that you are locking your package dojson idally with no carrot or no till day symbol as well don't use these symbol just remove them have an exact package version it's fine trust me it's fine do not randomly remove or you know delete your lock files whether that's pnpm lock yan lock or package lockjson whatever these file files are they are important files they are not meant to be just deleted and reinstalled every time there is some issue do not do that don't let your AI agents randomly install or update packages and fourth of all use like you know package manager feature to defer new installations for example there is literally a feature inside PNPM which allows you to mitigate these attacks which is called as where it is this minimum release age thing right so this minimum release age is a parameter edtor that you can specify in your configuration which would not allow you to install any package which is newer than that release right and I would probably you can keep it like 7 days I wouldn't mind but yeah most importantly just stay vigilant and stay safe on you know these things no point in installing these new packages as we have seen these sort of attacks are extremely common now and they are extremely devastating as well because if you lose your AWS account access keys things which should not have been in public by an attacker, that's going to be a company ending event for you. Could compromise your security, your data of your users. They can, you know, publicly extort you. They can publish your data.
They can do all sorts of bad things, right? So, it's it's actually super serious, more serious than people realize. So, that's all for this video.
Hopefully, you liked it. If you did, make sure to leave a like and subscribe to the channel. I'm going to see you in the next video very soon. If you're still watching, make sure you leave a comment, I watched till the end below, to tell me that you were still here. And let me know what do you think about the video.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 viewsโข2026-05-28
How agent o11y differs from traditional o11y โ Phil Hetzel, Braintrust
aiDotEngineer
450 viewsโข2026-05-28
Re: ๐ฃ๏ธ๐theprophedu๐2026 GST 103 CLASS (E-EXAM REVISION)
theprophedu
636 viewsโข2026-06-04
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation๐ฏโ
LearnwithSahera
1K viewsโข2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 viewsโข2026-05-29
Search Algorithms Explained in 60 Seconds! ๐ค๐จ
samarthtuliofficial
218 viewsโข2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 viewsโข2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 viewsโข2026-05-29











