In this blog post, we present one of the results from our wallet security research project—an EIP-712 implementation issue impacting more than 40 wallets. The importance of this finding lies primarily in the sheer number of affected vendors, as opposed to the practical risk it poses. It is important to emphasize that we followed standard disclosure practices and promptly notified the concerned teams, giving them ample time to address the issue.
Several months ago, Coinspect embarked on a research project focused on software wallets, with both high-level and specific objectives in mind. Leveraging our team of blockchain security experts and their vast knowledge in wallet security, the project aims to:
- Identify prevalent architectural patterns across software wallets,
- Create a comprehensive threat model, and
- Discover potential security vulnerabilities that might affect multiple wallets
Through this initiative, our objective is to contribute to the crypto ecosystem by improving the security and user experience of software wallets, as well as opening the discussion on software wallets security towards standard best practices. Consequently, the next milestone in this research project involves the publication of security best practices for software wallets. The results of this project will benefit developers, auditors, and wallet users alike, further strengthening and coordinating security efforts within the industry.
In subsequent sections we provide an extensive list of affected vendors, including reporting metrics such as bounties and response times. Furthermore, we present a concise overview of EIP-712, followed by a detailed analysis of the issue identified and an example demonstrating potential exploitation scenario. Finally, we share GitHub links containing the test DApps utilized during this investigation.
As indicated, this single issue impacted over 40 software wallets. Coinspect proactively contacted the development teams through various communication channels, including bug bounty platforms, email, and support tickets. It is worth noting that the list of affected vendors could be more extensive; however, we chose to focus on mainstream wallets at this stage of the investigation.
|Vendor||Status||Submitted on||Triage days||Fix days||Bounty ($)|
|Bitcoin.com||Couldn't reach out||N/A||N/A||N/A||-|
|Brave||Not accepted but fixed||25-Jan-23||6||9||-|
|Edge||Ack comm, not confirmed||24-Jan-23||N/A||N/A||-|
|Rainbow||Ack comm, not confirmed||24-Jan-23||N/A||N/A||-|
|Safepal||Ack comm, not confirmed||13-Jan-23||N/A||N/A||-|
|Spot||Couldn't reach out||N/A||N/A||N/A||-|
|Teleport||Couldn't reach out||N/A||N/A||N/A||-|
|Zelcore||Ack comm, not confirmed||23-Jan-23||N/A||N/A||-|
From the table above, several conclusions can be drawn:
- On average, it took wallet developers 10 days to triage reports based on the data provided.
- Teams who acknowledged the issue took an average of 29 days to address it after being notified, with resolution times ranging from 2 to 85 days and counting.
- Of the wallets affected, 51% have bug bounty programs in place. However, there have been instances where certain vendors either did not respond to submitted bug reports (e.g., 1inch), claimed the issue was out of their scope (Kucoin, Coin98), fixed the problem without awarding a bounty after initially dismissing it (Brave), or offered symbolic bounties.
- The highest bounty payout came from Coinbase via Hackerone ($2,000), while the lowest payouts were from Hashkey Me and imToken via BugRap ($100 each).
- Many bug bounty programs hosted on well-known platforms restrict the disclosure of bugs.
Taking into account the factors discussed (vendor postures toward bug reports, bounty amounts, response times, etc.), security researchers or bounty hunters can better manage their expectations and identify the most and least favorable wallets for bug hunting. However, it is important to note that this analysis is based on a single report, and therefore might not be entirely representative of a project’s overall approach to handling bug reports. A more comprehensive assessment would require examining multiple reports over time. Nonetheless, this case study highlights the potential of bounty programs as an excellent tool for improving security when utilized effectively.
EIP-712 defines a way to cryptographically hash and sign a typed JSON data structure. Particularly, this EIP features an
EIP712Domain data type present in every EIP-712 signed object, which declares the following fields:
- name: the user-readable name of the signing domain, i.e. the name of the DApp or the protocol.
- version the current major version of the signing domain. Signatures from different versions are not compatible.
- chainId: the EIP-155 chain id. The user-agent should refuse signing if it does not match the currently active chain.
- verifyingContract: the address of the contract that will verify the signature. The user-agent may do contract-specific phishing prevention.
- salt: a disambiguating salt
Most wallets failed to comply with the following directive when signing EIP-712 structures:
The user-agent should refuse signing if it does not match the currently active chain.
Plus, none of the wallets tested alerted the user when signing an EIP-712 object for a different chainId than the one selected.
A malicious DApp could potentially deceive users into signing EIP-712 objects for an EVM chain that differs from the one they intend to interact with.
Impact and Attack Scenarios
By obtaining signatures for arbitrary chains, adversaries can secure authorization for a specific protocol on a network of their preference. The consequences of such actions depend on the application and may result in a monetary loss.
EIP-712 is mostly used to sign typed structures off-chain, which can subsequently be validated on-chain to grant allowances for specific protocols. Therefore, a malicious DApp or phishing campaign could leverage this implementation weakness to gain allowance to a certain protocol on an arbitrary chain. The attack entails tricking victims into signing an EIP-712 typed data object containing the
chainId of the attacker’s choice in the
EIP712Domain struct. Upon acquiring a signed permit or approval for the target chain, the attacker could, for example, withdraw liquidity or execute unauthorized token transfers.
How to test the chainId validation issue on browser extensions
Coinspect adapted the Metamask Test DApp to provide the essential features necessary to test the present issue on browser extension wallets. The repository and setup instructions for the modified test DApp can be found at https://github.com/coinspect/test-dapp-eip-712.
How to test the chainId validation issue on mobile apps
Coinspect has forked WalletConnect Example DApp and modified it to provide extra signature verification details. The repository along with the instructions to set up the forked test DApp are located at: https://github.com/coinspect/walletconnect-dapp-eip712-test.