Decentralized apps (Dapps) are the cornerstone of Web3, enabling it to revolutionize the financial system and help users own their digital assets and content. However, the almost unlimited capabilities introduced by Dapps have created a new attack surface: Malicious Dapps that steal user assets based on opaque transaction approvals offered to and approved by the users.
To answer this visibility gap, transaction simulation technology has recently emerged and is quickly making its way into mainstream adoption in Web3 wallets and security extensions.
As part of Zengo wallet’s ongoing research into blockchain security and to support the expansion of our wallet’s built-in Web3 firewall (ClearSign), we have assessed the security of Transaction Simulation solutions offered by many leading vendors, including but not limited to Coinbase wallet, and found many of them vulnerable to attacks.
We have responsibly disclosed these vulnerabilities to the respective vendors and these issues are now fixed. For our efforts we had been rewarded with multiple bug bounties and an Ethereum Foundation grant.
Prior to Web3, blockchain application security was relatively simple. Blockchain transactions were standard and had only one functionality, directly initiated from the sending user: Transferring native tokens (e.g. ETH) from the sending user to the receiving user. In that model, users were aware of what they were doing and only needed to make sure the sums and destination address were correct.
The introduction of Web3 smart contracts has changed all, as it opened unlimited opportunities for decentralized apps (Dapps) and users. With smart contracts, anything that can be coded can be deployed on the blockchain, by anyone. As a result, in a Web3 environment, users’ blockchain transactions, previously used for sending coins to peers, are now actually Remote Procedure Calls (RPCs) to smart contracts.
The Web3 triangle: Dapps’ Web2 interfaces suggest transactions to users’ wallets for signing, then wallets send signed transactions to smart contracts that update back the Dapps’ Web2 interfaces.
The flip side of this expressiveness is that it’s almost impossible for users or their wallets to analytically know in advance what the outcome of a remote procedure call to an arbitrary smart contract will be (in fact, Computer Science Theory tells us that such problems are generally undecidable). This observability gap can be, and in fact is, abused by attackers to trick users into signing transactions that are actually harmful for them – in 2022 alone, over $3 billion dollars worth of cryptoassets were stolen. This is a vulnerability Zengo has begun to address with ClearSign, our built-in Web3 firewall.
Web3 security bears a close resemblance to the desktop environment: Users need to evaluate in advance confirming a transaction if a certain program behavior is good or malicious, without a curated application store.
To solve that observability gap, Web3 security was inspired by desktop’s existing security solutions, and is using a sandbox-style emulation to evaluate the potential outcome of the intended transaction, before it gets sent to the blockchain. In Web3 lingo, such sandbox emulation is often referred to as Transaction Simulation.
Transaction Simulation example
At Zengo, we partnered with Alchemy in order to power our Transaction Simulation solution, which will be seamlessly integrated with our Zengo’s Web3 Firewall and available to our wallet users in coming weeks.
The users’ (the top vertex of the Web3 triangle) security is in danger whenever either of the other vertices are malicious. Either when the smart contract is malicious or when the Web2 interface is suggesting malicious transactions.
Web3’s main attack vector: Malicious Web2 interfaces suggesting malicious transactions for users to send to legitimate contracts
Contrary to common belief or even common intuition, Web3 users’ greatest security risks do not lie in interacting with malicious contracts, but interacting with good contracts via malicious or corrupted (e.g. the BadgerDAO hack) Web2 interfaces!
The reason is that legitimate contracts (e.g. legitimate token contracts and legitimate marketplaces) are controlling some of the user assets. Therefore to steal them, attackers must abuse Web3 transaction opacity and suggest malicious transactions via rogue Web2 interfaces that will move these funds from the legitimate smart contract to the attackers.
In contrast, malicious contracts do not control any of the users’ assets (if they did, they would have taken these assets in the first place) and they have to persuade users to first send some native tokens to them under some false pretenses. Since native tokens transactions are quite visible, simulations are less needed. However, as we will see in the next section, insecure simulation implementations make the attack vector of malicious smart contracts even worse!
As we have seen above, Web3 defenders have taken a page out of the desktop security book to introduce transaction simulation. At Zengo we took a peek at the next page of this book, to find out how desktop attackers reacted to the introduction of simulations.
One of such ways is the “red pills attack,” the name of this attack inspired by The Matrix movie series. If malware is able to detect its actually being executed in a simulated environment (“living in the matrix”) it can behave in a benign manner thus deceiving the anti-malware solution, and reveal its true malicious nature only when actually executed in a real environment.
Take the red pill if you want to find out if you are living in the matrix
To import this attack vector into a Web3 environment, we need to find the smart contracts’ “red pills”: Some smart contracts’ instructions that may behave differently under simulation.
Sieving through all of Solidity’s (Ethereum smart contract programming language) instructions, we had set our sights on “Special-Variables.” These variables carry some general information on the blockchain functionality (e.g. the timestamp of the current block, the address of current block miner) or some information on the user controlled parameters of the transaction (e.g. paid fees).
These instructions looked like potential candidates to be “red pills.” Since these variables may take a range of values, that is no “correct” value for them. Therefore, it’s tempting for simulation implementers to “take a shortcut” and set them to some constant value. While these constant values are technically valid, they can serve as a “red pill” by savvy attackers.
For example, the “COINBASE” instruction contains the address of the current block miner. Since during simulation there is no real block and hence no miner, some simulation implementations just set it to the null address (all zeros address).
Therefore a malicious smart contract may weaponize this “COINBASE” red pill as follows:
Ask users to send some native coin to the contract, if COINBASE is zero (which means simulation in Polygon) the contract will send back some coins in return, thus making the transaction potentially profitable to the user when its wallet simulates it. However, when the user sends the transaction on-chain, COINBASE is actually filled with the non-zero address of the current miner, and the malicious contract just takes the sent coins.
This is exactly what is shown in the video below, in which we show how the “COINBASE” exploit can be used against Coinbase wallet users:
The victim users are shown by simulation that the transaction is highly profitable: If they send 0.1 MATIC (~$0.1), they will get 0.016 WETH (~$30) in return. However, when they actually send their MATIC they actually get nothing in return!
As a result, this vulnerable simulation implementation actually helps the malicious smart contract persuade its victims into sending their funds to it. Users would have been better off without this wrong simulation!
We were surprised to find that almost every simulation implementation that we had inspected was vulnerable to one or more variants of the red pills attack.
The above table shows vulnerable extensions, wallets and simulation vendors (additional unnamed extension not yet fixed).
All vendors were very receptive to our reports, and most of them were quick to fix their faulty implementations.
The fixes themselves are relatively straightforward: Instead of populating these vulnerable variables with arbitrary values, the simulation need to populate them with meaningful values, e.g. last block’s miner in COINBASE (consecutive blocks by the same miner may happen on-chain), or the user selected fee for GASPRICE.
Some of these vendors awarded us bug bounties for our efforts.
Multiple bug bounties awards from the Coinbase wallet
Others gave us a shoutout on Twitter:
While web3 is a relatively new concept, defenders do not have to reinvent the wheel when it comes to its security. Many of the solutions and countermeasures can be adapted from some older and more mature security domains.
Transaction Simulation, inspired by anti-malware sandbox security solutions, can be a highly useful tool in defenders’ toolbox, providing much-required visibility into opaque Web3 transactions. This visibility should be leveraged by a Web3 firewall to alert users against malicious transitions.
However, when not implemented securely, transaction simulation may backfire and actually help attackers defraud users out of their assets. (As a side note, the much discussed Account Abstraction [AA] technology requires some new additional construction to avoid AA red pills).
It’s important to note that simulation is not a silver bullet for visibility and it does not cover some critical aspects such as offline signature security, for which other visibility solutions are required such as our proposed ERC-6384 standard.
We hope that by publicly sharing our findings we can make the Ethereum ecosystem a safer place for all its users.