What happened, are you affected & how to prevent - axios supply chain attack

MMaximilian Schwarzmüller
Computing/SoftwareBusiness NewsInternet Technology

Transcript

00:00:00This is serious and no joke, it's been a couple of rough hours, because there has been
00:00:06a huge supply chain attack on Axios, yes, that Axios that has more than 80 million weekly
00:00:14downloads.
00:00:15Now, first things first.
00:00:18In order for you to check if you're affected, attached you find a link to an article, and
00:00:23I'll share more details in a second, but this is important, for you to check if you
00:00:27have been affected, you want to follow that link below and run the commands you see there
00:00:32for your operating system, Mac OS, Linux, Windows, they're all affected.
00:00:37You want to run these commands if you are affected.
00:00:40And especially if these steps here show that you have been compromised, you will need to
00:00:49rotate your secrets, change your passwords, consider your credentials, the API keys on
00:00:55your system, everything that is on your system, stolen.
00:01:00Consider your password stolen, change it all, disable the API keys, this is really important.
00:01:07Now, what exactly happened?
00:01:09Axios, obviously very popular JavaScript library, a library that can be used to send HTTP requests
00:01:17from for example, a React app to a backend API.
00:01:22It's getting used a lot, as you can see, and some malicious code has been injected into
00:01:28this library.
00:01:29Now, this does not mean that the websites that use that library have been affected.
00:01:36It means instead that the systems where you installed that library, your MacBook, your
00:01:41PC, or maybe that VPS where you built your website, those have been compromised.
00:01:50If you ran npm install, bun install, npm update, bun update, anything like that in the last
00:01:57couple of hours, there is a high danger that you have been affected.
00:02:00Again, I shared those checks you should run to check whether you have been affected.
00:02:05Now, how exactly did this all happen and what exactly is a supply chain attack?
00:02:10I'll also share, by the way, how you can secure yourself against attacks like this in the future.
00:02:15But first, let's understand what exactly happens and what a supply chain attack is.
00:02:20A supply chain attack is simply an attack that does not target your application code.
00:02:24The attacker doesn't try to directly infiltrate your system or your code base instead.
00:02:31They leverage the fact that your application code typically has dependencies, which themselves
00:02:37have dependencies.
00:02:38So you have that dependency change and the attack that targets this dependency chain.
00:02:45So it happens upstream from your code.
00:02:48So one of these dependencies has some malicious code due to an attack where that code was
00:02:54injected into it, not because the maintainer is trying to attack you.
00:02:58But instead, for example, like in this case, the account of a maintainer gets compromised
00:03:03and the attacker uses that to then inject malicious code into some library, into some package,
00:03:10which another package may then be using and your code may then be using that package that
00:03:16uses the malicious package, or maybe your application code directly pulls in the malicious dependency.
00:03:23Either way, one of your dependencies now suddenly comes with some malicious code.
00:03:28And the moment you run npm install or anything like that, or you update that package gets
00:03:36downloaded onto your system, that malicious one, that affected one, and then it can execute
00:03:41malicious code on your system, typically with help of post install scripts.
00:03:47So in case you don't know, npm has this mechanism of scripts.
00:03:56We're all using them in our projects, for example, to start a dev server, to build our project,
00:04:01to run tests, stuff like that.
00:04:04And there specifically also are post install scripts, which you might not be using when
00:04:11you're building a React app, for example, but which libraries often use or may not often,
00:04:17but may use to run some code on your system after you install the library, typically not
00:04:23to do anything malicious or bad, but for example, to compile some code, create a binary that
00:04:31may be needed by that library, prepare your system in any way or form so that it can actually
00:04:36use that library you just downloaded.
00:04:40That is the idea behind a post install script.
00:04:42It allows a package to define some code that should be executed after it has been installed
00:04:49through npm install, for example, and that's exactly what gets leveraged typically in those
00:04:55supply chain attacks.
00:04:57The attacker injects some malicious code into a package that is essentially a post install
00:05:04script that is executed automatically once the infected package has been installed.
00:05:10Typically that code is obfuscated so that it's not easy to read.
00:05:14It could be base64 encoded so that scanners that scan packages for malicious code might
00:05:20not detect it and or the malicious code may be downloaded.
00:05:24So the post install script, like in case here of the access attack, actually doesn't directly
00:05:30contain the malicious code.
00:05:32Instead it contacts a server and downloads the code from there.
00:05:36That is what happened here.
00:05:37And we have a detailed report on what exactly happened during that attack.
00:05:41You find that attached if you want to read all the details, but in there we essentially
00:05:45learn that two versions of the access package, 1.14.1 and 0.30.4 were affected, were compromised
00:05:57in the end and that was done by the attacker getting access to the account of one of the
00:06:02access package maintainers and they used that account to publish a new version of the access
00:06:08package that contained a dependency which then in turn contained that post install script.
00:06:14So it was not even the access package itself that contained the post install script, but
00:06:19instead it was another package, the plaincryptojs package, which was created by the attacker,
00:06:25which sole purpose is to have a post install script that downloads and runs some malicious
00:06:31code.
00:06:32So the access package was compromised by adding plaincryptojs as a dependency to access.
00:06:39That is a malicious package.
00:06:40It serves no other purpose than downloading that malicious code and just by adding this
00:06:46dependency to Axios, the attack was finished essentially.
00:06:52This package is not imported into the Axios source code anywhere.
00:06:56It just has this post install script and that is it.
00:06:59As mentioned, it then is able to download and run code from echo as Windows and Linux to
00:07:05then do what?
00:07:06Well, steal a bunch of stuff.
00:07:08So if your system is affected, as I mentioned initially, credentials, API keys, crypto tokens,
00:07:14all that fun stuff is being collected and exfiltrated by a trojan that is downloaded by that post
00:07:21install script.
00:07:22That is how that attack worked.
00:07:24That is how similar attacks worked in the past.
00:07:29Now what's kind of interesting, well, oh, by the way, this attack started around midnight,
00:07:36exactly after midnight UTC today, a few hours ago.
00:07:40It lasted for a couple of hours and both Axios versions 1.14.1 and 0.30.4 were affected within
00:07:5040 minutes, essentially 39 minutes to be precise.
00:07:53So this was a very orchestrated planned attack.
00:07:56Obviously the creation of this extra package happened I think 18 hours before the attack
00:08:03started.
00:08:04It was very orchestrated and planned.
00:08:06Now what's a bit weird here is that NPM has this mechanism called trusted publishing, which
00:08:14can be used by package maintainers.
00:08:17And the idea here is that that limits the publishing process of new versions of a package to a clearly
00:08:26defined process where specifically you have to build and publish a new version through
00:08:32one of these supported CI/CD providers with a certain setup you have to go through.
00:08:38And the idea here is that even if your NPM account credentials get stolen, in theory,
00:08:46the attacker can't publish a new version of your package from their machine because they
00:08:51need to go through that process.
00:08:52Now you could argue that if the GitHub account of a maintainer gets compromised, then maybe
00:08:59a malicious version can be pushed to GitHub, triggering that deploy workflow here and therefore
00:09:06the malicious code gets published through that trusted publishing process.
00:09:11But according to the security report here, that is not what happened here.
00:09:16Because the access team is using this trusted publishing process for the 1.x branch, not
00:09:21for the 0.30 branch, but for the 1.x branch.
00:09:26But according to this report, there is no commit or attack in the access GitHub repository.
00:09:33So there wasn't a push to GitHub with that compromised version of Axios.
00:09:40So the trusted publishing process shouldn't have been triggered.
00:09:44Instead, this report states that the attacker must have obtained a long-lived classic NPM
00:09:50access token for publishing this malicious or this compromised version of Axios because
00:09:56the release only existed on NPM, not on GitHub.
00:10:01Maybe this is wrong.
00:10:02Maybe the attack went through GitHub.
00:10:05If it is correct, though, it's not clear to me how exactly it worked because in theory,
00:10:11this way of publishing should not be possible when trusted publishing is turned on.
00:10:15Not sure if this is some security vulnerability or some problem with NPM here.
00:10:20That some existing long-lived tokens could still be used even with trusted publishing
00:10:26turned on.
00:10:27That is something I was not able to find out how exactly that worked out.
00:10:32And there is a threat here, a GitHub issue on the Axios library where this attack was
00:10:39reported.
00:10:40By the way, side note, more such issues have been created and they were deleted by the compromised
00:10:45maintainer, by the account of the compromised maintainer.
00:10:48This threat, this issue survived and the attack was stopped eventually.
00:10:52They regained access to their account, that maintainer that was affected.
00:10:56And in that threat, in that issue, the maintainer posts and said that they are using trusted
00:11:03publishing and it's not clear how exactly that worked.
00:11:07Here is a theory that was shared.
00:11:09But my understanding is that this theory would still require a new malicious or compromised
00:11:16version being pushed to GitHub, but again, that's all not clear.
00:11:20What is clear is that compromised versions have been published and ended up on NPM and
00:11:25therefore could be downloaded on systems and steal stuff there.
00:11:29And of course with over 80 million weekly downloads, there is a lot of damage to be done within
00:11:35a few hours.
00:11:37Obviously downloads are not evenly distributed across all hours during a day, but this is
00:11:44definitely a huge number and we can assume that thousands, tens of thousands of systems
00:11:51have been affected within those few hours.
00:11:55Now of course this wasn't the first supply chain attack.
00:11:59Over the last months we've seen multiple attacks.
00:12:01One big attack at the end of last year, the shy hulu attack where multiple packages were
00:12:08executed on NPM and that had a similar pattern, malicious code being injected and executed
00:12:16on systems that downloaded those compromised packages and then credentials and stuff being
00:12:21stolen.
00:12:22So that is one big attack.
00:12:25And then only a few days ago we had a similar incident in the Python ecosystem.
00:12:31So it's not limited to JavaScript where the lightllm package was affected.
00:12:37Very popular package that in the end makes it easier to use AI providers through one convenient
00:12:43interface that also had a similar attack and was affected.
00:12:49And therefore it's of course not just JavaScript.
00:12:52And I think there are a couple of reasons why we see more such attacks happening.
00:12:57Because in theory, these kinds of attacks could have happened and probably did happen in the
00:13:03past too but clearly they are becoming more frequent now and I think there are a couple
00:13:08of reasons for that.
00:13:11Now of course one big reason is that we're at a point in time where more code than ever
00:13:17is being written, generated.
00:13:19I mean you can look at various metrics.
00:13:22For example I saw this chart recently that the number of new GitHub repositories being
00:13:27created is at an all-time high and of course that is because of AI.
00:13:31Where people are working on projects, are generating code.
00:13:35We have more code output than ever before and of course that means with so much more programs
00:13:42being written, so much more code being generated, the attack surface is so much bigger.
00:13:47There are more targets.
00:13:48There are more people building or writing code and installing packages.
00:13:52So it's more attractive than ever.
00:13:54Not that it was not attractive in the past but now there are more people than ever that
00:13:59can be attacked.
00:14:00So that's of course one big reason.
00:14:03It's simply more interesting to run these attacks but it's not the only one.
00:14:07I think another reason of course also is related to AI that for one, running such attacks like
00:14:15this with help of AI probably got easier for one because the malicious code can of course
00:14:21also be generated and written with help of AI so the technical skills needed to run such
00:14:28attacks are more available than in the past I would argue, though you could also buy scripts
00:14:33or trojans like this in the darknet but still it might be more accessible to people.
00:14:40It's of course not just the good side of AI that more people can build software and turn
00:14:46their ideas into businesses or whatever but it's also the bad stuff.
00:14:50More people can do bad things related to code thanks to AI so that is one reason.
00:14:55You could also argue that of course package maintainers, library maintainers are swamped
00:15:01with pull requests.
00:15:02That's another big issue we have these days that if you're an open source maintainer there's
00:15:07more pull requests coming in than ever before so you might not be super careful with what
00:15:13you merge.
00:15:14Not the problem here just to be clear.
00:15:16In this access attack here clearly it was a compromised account but you could in theory
00:15:22make the argument that it would be possible that maintainers merge malicious code or code
00:15:29that installs malicious dependencies into their library because they just overlook it or maybe
00:15:34because they have a fully automated code review process that doesn't catch it.
00:15:38They're just relying on AI.
00:15:40Again not the case here but you could think that this could in the future be used by attackers
00:15:45that they inject malicious code into code bases because people just don't look.
00:15:51In addition when you're using Cloth code, OpenCloth whatever on your system to do all
00:15:56kinds of work for you not just help you work on software but maybe just manage your system
00:16:01as a whole of course for certain tasks OpenCloth, Cloth code, codecs whatever they may decide
00:16:09to write some script and run some code to do a certain task you ask them to do and that
00:16:15code they generated may also rely on dependencies like access.
00:16:20So again the attack surface getting bigger that's my first argument again but outside
00:16:24of just classic software development and for all these reasons and probably many other reasons
00:16:30I didn't think about here these attacks are getting more lucrative easier to do and more
00:16:37interesting to do and that is why I'm certain we'll see more of these attacks in the future.
00:16:43Now what can you do to prevent such attacks to protect yourself?
00:16:47One big security step up one thing you can do is in all your projects where you are working
00:16:55on applications and so on when you're using tools like pnpm instead of npm for managing
00:17:02your dependencies you can add a minimum release age setting to your pnpm workspace yaml file
00:17:09bun has a similar feature you can add a bunfig.toml file if you're using bun as a package manager
00:17:15and they also have a minimum release age setting you can add in that file what does this do
00:17:21it simply ensures that whenever you install a package no matter how it only installed packages
00:17:27that are at least that old or package versions that are at least that old so if a package
00:17:34was compromised five hours ago but you have a rule that only installs versions that are
00:17:39at least three days old you should be safe that is the idea and unfortunately npm itself
00:17:46doesn't have that now just to be sure or that this is clear we're still talking about packages
00:17:51that are hosted on npm that is not the problem i'm talking about the package manager here
00:17:56and you can of course use bun or pnpm to download those packages from npm and if you are using
00:18:03them instead of just npm the tool itself then you can take advantage of settings like this
00:18:08which simply give you that extra security layer because typically in the past those attacks
00:18:14have been caught within a couple of hours so if you have like a three day threshold for
00:18:20example most of these attacks will have been caught by then and will be over it's not 100%
00:18:25secure of course an attack could last for longer but it gives you a clear advantage and it's
00:18:32definitely a good thing to do now to be even more secure you can and should consider using
00:18:39solutions like doppler and this is not sponsored this is just one example there are alternatives
00:18:44i built my own alternative actually which i'm using myself which are services or tools that
00:18:49manage your secrets so something like your open ai api key you could put that in a dot
00:18:55n file but it's better to store it encrypted in or with help of a service like doppler on
00:19:02their servers or on or self-hosted on a vps you own and then you inject it into the environment
00:19:08for your application to be aware of it and to use it when needed so that if you had a
00:19:13troian on your system that maybe fetches all your dot n files and extracts the information
00:19:20out of them it doesn't find any secrets in there that's the idea so storing those secrets
00:19:25not in text files on your system and a dot n file is just a text file in the end but instead
00:19:32encrypted somewhere else is definitely also something you might want to consider doing
00:19:36and again there are different solutions here but it is something you might want to consider
00:19:40and to be even more secure of course you could outsource your development environment and
00:19:45not have it on your macbook your machine your pc but instead have it on a vps on a mac mini
00:19:50to which you connect via ssh or something like that or maybe in a docker container so that
00:19:56if some malicious code would be executed there it only affects that docker container that
00:20:02vps and not your entire system so it can't gather all your system passwords and stuff
00:20:07like that instead it's isolated you have a smaller blast radius because those attacks
00:20:13will keep on happening obviously i'm pretty sure we'll have better and better mechanisms
00:20:21to secure publishing of packages and so on but there will never be a 100 guaranteed that
00:20:27such attacks can't happen and therefore you as a user of such packages you must secure
00:20:33your system and have multiple layers of defense there so that you decrease the chance of you
00:20:39downloading a compromised package version and if you do there the blast radius is smaller
00:20:45that is what you can do i'll share more on that in future videos also on my other channel
00:20:50the academy channel but yeah stay safe out there check if you have been affected by this
00:20:55attack and yeah it's been a couple of rough hours as i mentioned

Key Takeaway

The Axios supply chain attack leveraged a compromised maintainer account to inject the plaincryptojs dependency, exfiltrating credentials from tens of thousands of systems through automated post-install scripts.

Highlights

Axios versions 1.14.1 and 0.30.4 were compromised via a malicious dependency named plaincryptojs injected through a maintainer's account.

The attack exfiltrates system credentials, API keys, and crypto tokens using a trojan downloaded by a post-install script.

The malicious versions were published to NPM approximately 18 hours after the attacker created the plaincryptojs package.

Systems are at risk if npm install, bun install, npm update, or bun update ran during the few hours following midnight UTC.

Setting a minimum release age in pnpm-workspace.yaml or bunfig.toml prevents the installation of versions less than a few days old.

The attack bypasses Trusted Publishing on the 1.x branch despite no malicious commits appearing in the Axios GitHub repository.

Timeline

Immediate impact and recovery steps

  • Axios serves over 80 million weekly downloads, making this supply chain attack a high-scale security event.
  • Compromised systems require a full rotation of secrets, including passwords and API keys.
  • Users must run specific operating system commands to verify if their local environment or VPS is infected.

The severity of the breach stems from the massive reach of the Axios library across Mac OS, Linux, and Windows systems. If initial checks show a compromise, all credentials on the machine are considered stolen and must be invalidated immediately. This includes everything from local system passwords to cloud service API keys.

Mechanics of the plaincryptojs injection

  • The attack targets the dependency chain rather than the application code itself.
  • A malicious package called plaincryptojs was added as a dependency to Axios to execute a post-install script.
  • The post-install script downloads a trojan from a remote server to collect and exfiltrate user data.

The attacker gained access to a maintainer's account and published versions 1.14.1 and 0.30.4 with the malicious dependency. This package, plaincryptojs, exists solely to run a script after the installation process completes. Because the script downloads code from an external server, it can bypass some static scanners that look for hardcoded malicious strings.

Bypassing NPM Trusted Publishing

  • The attack on version 1.14.1 occurred despite the use of Trusted Publishing, which typically requires a CI/CD workflow.
  • No malicious commits or tags exist in the official Axios GitHub repository for the compromised versions.
  • Evidence suggests the attacker used a long-lived classic NPM token to publish directly to the registry.

Trusted Publishing is designed to prevent manual uploads by linking the publishing process to specific GitHub Actions. However, since the malicious release only existed on NPM and not on GitHub, the attacker likely exploited an existing classic token that remained active. This highlight a potential gap where long-lived tokens can still function even after a project migrates to more secure publishing methods.

Rising frequency of supply chain threats

  • AI-generated code and the surge in new GitHub repositories increase the global attack surface.
  • Recent incidents include the Shai Hulu attack on NPM and the lightllm package breach in the Python ecosystem.
  • Open-source maintainers are increasingly overwhelmed by a high volume of pull requests, making manual review difficult.

Supply chain attacks are becoming more lucrative as more people write and deploy code using automated tools. AI assistants like Claude or Copilot may generate code that pulls in compromised dependencies, further spreading the risk. The shift toward automated review processes also creates opportunities for attackers to slip malicious code past human eyes.

Defensive strategies and environment isolation

  • Package managers like pnpm and bun support a minimum release age setting to filter out brand-new, potentially unvetted versions.
  • Secret management tools like Doppler prevent trojans from finding plain-text credentials in .env files.
  • Development environments can be isolated within Docker containers or remote VPS instances to limit the blast radius of an attack.

Implementing a three-day threshold for new package versions can catch most attacks, as they are typically identified and removed within hours. Storing secrets in encrypted management services rather than local text files ensures that even if a system is breached, the attacker cannot easily read the API keys. Moving development off the local machine and into a containerized or remote environment prevents a compromised package from accessing the host operating system's sensitive data.

Community Posts

View all posts