Zero-Click Argent-X Wallet Contract Vulnerability, Explained
TL;DR
We’ve found a critical vulnerability in Argent contracts deployed with version 5.0.x of the Argent-X wallet application, which allows anyone to gain full control on an Argent account. The vulnerability is exploited by sending a transaction in a certain way that bypasses Argent Contract signature verification logic. This would allow an attacker to send any transaction with an empty or false signature that would get executed and accepted on-chain. We’ve demonstrated the vulnerability by sending a Transfer transaction with an empty signature to an Argent account contract and transferring ETH to a wallet of our choice. We communicated about this problem to Argent, and it acted quickly to address it.
A Tale of Two Versions
In the recent StarkNet v0.10.0 released about over a month ago, the protocol introduced a new transaction version level (v1). It changes the way Starknet Account Contracts should verify transactions by separating transaction validation logic from transaction execution logic (the verification itself is still done as part of the account contract — but now the StarkNet OS is calling it). This is beneficial as it allows the StarkNet OS to verify the transaction’s validity before running it, thus preventing DDoS attacks from an attacker that cannot produce a valid signature.
The support for transactions running with the old version (v0) was still intact to allow users to gradually migrate to the new OS-account contract verification scheme.
Since the OS supports both transaction versions (v0 and v1), the account contract also has to support both.
The Signature Validation Process
The power of smart contract based wallets (a.k.a Account Abstraction) is that it allows, among other things, an arbitrary verification logic. But as they say, with great power comes great responsibility.
Allowing arbitrary verification logic means that the account contract can decide which verification logic to run — It can either execute the native protocol verification or run a verification coded independently.
(again, the difference between transaction v0 and v1 is who calls this verification logic function — the contract or the OS).
However, in the current state of the network, an account should expect to get both kinds of transactions but can decide that it supports only the newer transaction version — v1.
The Vulnerability
In the latest Argent contract implementation, which was deployed to the network on November-4 and was available as part of the Argent-X v5.0.x earlier this week, there was an implicit assumption that the contract will handle only v1 transactions, as can be seen in the code snippet below. However, the assertion was placed in the verification function which in the case of transaction v1 is called by the OS, but in transaction v0 should be called by the __execute__ function of the contract.
Thus an account contract that wishes to support v1 transaction only, should place the version assertion in the __execute__ function as the OS does not call the __validate__ function.
Implications
Given the above vulnerability, an attacker can send any v0 transaction with an empty (or gibberish) signature and it will pass through with no issue and will be included as a valid transaction in the block.
It is important to note that this is a zero-click attack that does not require any user action or interaction. An attacker could have simply gone over all new and updated Argent accounts deployed and transferred all the assets from each and every account to an account of their choice.
Discovering the issue
In Braavos we strongly believe and thus put high emphasis on tests. Especially contract tests. As part of our preparations towards releasing our wallet support for v0.10.x we’ve created an extensive test suite and during this process, this subtle issue of where to verify the transaction version came into play.
As this is a pretty delicate issue that is hard to reproduce with standard Starknet Dev tools, we thought that it might escape other account contract developers, so as soon as we finished our set of tests, we shifted our focus to check if this is a real issue or just a fallible concern.
And Indeed, when we started checking the Argent account contract, in no time, the issue manifested itself. We were able to reproduce the vulnerability very quickly.
The following is an example of a transaction accepted on-chain issued directly to the Starknet infrastructure without any Wallet Application interaction. The transaction signature is an empty signature and transfered ETH from a vulnerable Argent account to an arbitrary account.
https://starkscan.co/tx/0xe822d983f9c5d3ff320037812633435edcd71afa725e16d84af700973b0da
Responsible Disclosure
On Wednesday night, November-16, once the first transaction with no signature had passed, we immediately understood the severity of the problem and the potential damage to users. In order not to cause unnecessary havoc, we double-checked that and reproduced it again.
At Braavos, we are committed to responsible disclosure, even to ”competitors’’ as we believe this is the right thing to do.
Furthermore, our main concern is the prosperity of the ecosystem and the safety of users’ funds.
Timeline of events
- On 4-November-2022 a new Argent implementation contract was deployed on-chain
- On 14-November-2022 a new Argent-X extension application was released that makes use of the new implementation contract for new, as well as for upgraded accounts
- On 16-November-2022 at 21:23 CET Braavos team was able to issue a transaction with an empty signature that transferred funds from a compromised Argent account
- At 22:01 CET the Braavos team reported the vulnerability to the Argent team over Slack — providing all the details on the issue, how to reproduce it and the on-chain example of malice transaction, as well as what needs to be done to fix this.
- At 22:11 CET the Braavos team alerted Starkware team over Slack as well, so they could make sure Argent saw the message at such a late hour.
- At 22:35 CET the Starkware team responded and tried to get a hold of Argent
- At 22:43: CET the Argent team acknowledged that they saw the message and were on the issue
- At 23:53 CET the Braavos team suggested Starkware to take a temporary measure and limit such transactions to prevent loss of funds until a fix is rolled-out*
- On November-17 at 1:03 CET Argent updated and they submitted a new version for approval in the stores. The version was made available publicly a short time after
- On November-17 around 14:00 CET Starkware issued an update to the StarkNet OS, implementing Braavos suggested temporary measure that started blocking such impacted transactions
Urgency
(*) — we knew that even if Argent would release a fix within a few short hours (as indeed happened!), it could take time until the patched version will be approved in the Chrome store and even more time till users will upgrade to the new contract. Thus, we continued working with the Starkware team to try and patch a solution at the protocol level. Then we suggested blocking v0 transactions to this specific Argent contract implementation and thus ensuring that an attacker will not be able to take advantage of the situation in the few days it will take all relevant users to upgrade their Argent wallet + account contract to the fixed version.
We appreciate the fast and concise execution of the Argent team in addressing the issue and submitting a fix to the stores within 3 short hours of reporting. We also appreciate the Starkware team that did not regard this issue as a dApp/wallet problem. It was fully committed to doing all in its power to make sure users won’t be in jeopardy.
Due to the fast action by all parties, no funds were lost.
Conclusion
We are confident that smart contract based wallets are the future as the flexibility. It enables opens the door for a significantly better UX while not compromising on security.
It will allow wallets not to compromise on security, while giving everyday users the experience they are used to from classic tradFi/web2 solutions.
The StarkNet ecosystem is still in its alpha stage and as such, it is expected to move fast and introduce changes and upgrades that will push the overall functionality of the network forward.
It is up to all the developers working on the network to be extra careful and TEST TEST TEST!