The NPM Supply Chain Attack: A Wake-Up Call for Trustless Verification

EDCON 2025 · 19 Sept 2025 · 20:19

Steffen Kux examines the September 2025 compromise of NPM packages including chalk and debug, and the wallet-draining code introduced through software dependencies. He uses the incident to argue for stateless, verifiable clients such as colibri.stateless and to question applications’ implicit trust in third-party code.

Speakers

Topics

From EDCON 2025, hosted by EDCON.

Transcript

Please welcome [Musik] after this light and exciting topic we heard right now I have to make it a little bit darker zusammen NPM attack recogn attack could very strong impact on the

web community thanks Jan Sterk from Germany who discovered this attack and a lot of people in the community attack was detected very quickly and solved inside attack web community web development what could and do better in the future.

Before we start some words about trust trust is something very special. So I trust my wife, I trust my friends, I even trust my business partners. But when it comes to the web free development, we should be very careful about trust. So often talk about trustless systems. So even if I use this word, it's not really correct. So there is no trustless system but we have also to talk about trust assumptions. So first of course when we talk about the users of our applications we should not trust that users are not doing anything malicious or try to do

something what should not do in our apps. I think it's clear when it comes to hardware and operation systems of our computers. bar to trust doing what do impact of test but not that much influence cloud providers information providers service providers should we trust them should we trust what they deliver to us we should not always try to verify using in softwares dependenci packages

open source software great idea real big fan of open source if we use such libraries we have to think about how much trust can we give into systems ends what software dashboard where show of course a library breaks not nice software might not work expected but if building a security relevant application I don't have to trust any software

component any Most of our web free applications at the moment written in JavaScript and to be honest I never understood why we chose JavaScript one of the main languages to build such applications. So I work for several years in the automotive industry.

wenn wir deploy software in the cars the rules what needs done what software needs to do very strong was a lot of rules that prevented something like dynamic code execution when we go to JavaScript actually this language wased for complete different reason it was to developed animations in page interactions make websites more attractive more nice more convenient

but now we are building a lot of different applications and even security security relevant applications javascript what problems look at javascript regarding compile time over global information global variables global functions so change behavior of the application from outside don't standboxes a lot of dependencies

NPM packagesen number dependen package using a lot of different packages maybe tens even hundreds of direct or indirect dependencies in back to automotive industry when I wanted to use a single function from a package in Ja using packages come and trust that are not infected by malous code.

So what happened some days before and we will see exactly these things I just talked about. Jaasons foundation September 8 information available in social media stop using our wallet not do any signatures not do any interactions blockchain because was happening malicious in widely used npm packages.

So how did happen? was a targeted fishing attack to a developer who was involved in a lot of different packages and the injected some code which changed the addresses of transactions so that the receiver address replaced by a similar looking address in from the attacker so this code was injected using packages

code application operation background interface means everything happened in the background hiden user could see Interesting was no RBC infected, der was no wallet infected, der seed stolen, but transactions send money to the front address. It was just code which was used by the app was trust that was infected.

So, what kind of packages infected? So in the first side we would think okay if the infected some cryptographic packages or some web free packages this could be could could have impact but if you go to this list of all these packages you will see these are packages for font manipulation color manipulation for some debug functionalities and so on none of packages crypto packages means packages application

very bad behavior. How exactly work one of packages was used then it in it replaced some global functions fetch function for instance global fetch function provider and manipulated them and then when there was an interaction application with the wallet for instance wallet you sign the transaction you want to send one e address receiver address similar looking addresser

user information in wallet user would not read exactly if the right receiver address would sign this attack sign transaction doing regular transaction differ so

went in background so user interface expect time wallet signature little difference in address so why could this happen so what was the reason that something like this could happen so we have a lot of trust assumptions and a change of trust in our applications and especially also in our web 3 applications. So first we are using packages from MPM and as I showed

even if I use only a simple small package for UI manipulation it could have impact to any other position in my code. The other thing is we often trust our PC providers that they really deliver us the right information. I will not go in detail with this. I will talk later this day about die the topic trusting OBC providers but this is also a problem we have in most of our web free applications.

Ja often we notice der transactions generated and signed and sent without testing if the sign transaction is really this what it should be. So what do we really need to do to prevent this happening? We must see that give attackers not only a way to break our assumptions. Trust assumption in our code very easy for the attacker to do something which is not that what we want to have in our applications.

So I have to repeat don't trust always verify everything. We have to verify any aspect in our application. and do not oder build trust chains in our applications. So what can we do to detect such misbehavior like it was in this attack? So first ja we should not trust any input we get fromc provider unfortun not saved us in attack also very important point is we should never send untested

transactions to the network so even if I build a transaction in my application I have to check vector locion docal simulation so jaun Note in application etum

browser so running browser which was the execution environment for smart contracts for decent applications it had an included etum note synchroniz you had local node and you had all information to be trustless But as we know talked about way too big for most applications you cannot run a full note in your web application in your mobile application not possible then we have light cin lights are very interesting in nice evolution so lights don't synchronize

the whole chain only some parts of it the block headers and some information which are really needed run all time missing blocks smartone application users will be not happy if you are synchronizing all the day even only a small piece of header in in der blockheader.

So what can we do? We should oder we need to use stateless but fully verifying clients. That means we have to use clients which can can be able to get information get proof that information is correct and no synchronization no state but full trustless verification. And statlesseless clients also need to verify all information before sent to the blockchain.

stats also in development like Helios client heavyweight and others providing technologies we can use to do verification in our applications need to do so could been prevented using client transaction verified means

transaction generated sent to be signed in the wallet and before delivered to the network again checked in case receiver address and transaction and so transaction would never have been sended to the network.

So already mentioned stat completely not synchronizing blockchain just getting information getting the proof in other talk I have at o I will go deeper into the mechanism we can use this client already to really have trustless connection to blockchain by validating all information we get blockchain simulation locally before send me give a short summary. So this attack was a very critical attack thanks to the quick action of the community and good

portion of luck. It was detected very quickly so that we could stop it before a lot of of impact could be seen in the network. So that means even if this was a critical attack it the impact was not that bad but it have could been we never can fully protect us from supply chain attacks but we should do as much as we can do to ja prevent this from having a big impact so one thing everyone can do reduce your dependencies the Best application is zero dependencies. Of course is not possible

but if we use some dependencies we have to check them. So if you say that's not feasible if I use these packages I have let's say 20 dependencies I cannot check every dependency then you should not use these packages in security relevant applications. verify versions audited versions secure.

Ja. Never use unverified code, never use unverified transaction data. Never use information blockchain not verified and verify always do it locally in device in application so that you can be sure no attack vector can manipulate this data. Once again, don't trust, verify everything. Stay safe. Thank you much. [Applaus] [Musik]