Software wallets research series: EIP-712 implementation issue impacting 40+ vendors Cover

Software wallets research series: EIP-712 implementation issue impacting 40+ vendors

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.

Impacted vendors

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 ($)
1inch Not accepted 23-Jan-23 44 N/A -
Alpha Fixed 27-Jan-23 - 31 -
Bitcoin.com Couldn't reach out N/A N/A N/A -
Bitizen Fixed 23-Jan-23 25 37 400
BitKeep No response 24-Jan-23 N/A N/A -
Bitpay No response 23-Jan-23 N/A N/A -
Brave Not accepted but fixed 25-Jan-23 6 9 -
Coin98 Not accepted 18-Jan-23 7 N/A -
Coinbase Fixed 14-Jan-23 5 - 2000
Coolwallet Fixed 23-Jan-23 18 - 450
Core Fixed 15-Jan-23 3 18 250
Crypto.com Pending fix 14-Jan-23 5 Ongoing -
Defiant Pending fix 24-Jan-23 0 Ongoing -
Edge Ack comm, not confirmed 24-Jan-23 N/A N/A -
Enkrypt Fixed 13-Jan-23 0 5 -
Exodus Fixed 14-Jan-23 3 28 1250
Frontier No response 7-Mar-23 N/A N/A -
HashKey Me Fixed 23-Jan-23 15 46 100
imToken Fixed 23-Jan-23 21 37 100
Kucoin Not accepted 23-Jan-23 8 N/A -
Liquality Fixed 13-Jan-23 - 12 -
Mathwallet No response 13-Jan-23 N/A N/A -
Omni No response 30-Jan-23 N/A N/A -
OneKey Fixed 19-Jan-23 - 19 -
Oxalus No response 24-Jan-23 N/A N/A -
Phantom Fixed 14-Feb-23 16 52 200
Pillar Fixed 18-Jan-23 16 27 250
Rabby Fixed 13-Jan-23 3 5 500
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 -
Stargazer Fixed 10-Jan-23 1 2 -
Teleport Couldn't reach out N/A N/A N/A -
Trust Wallet Fixed 15-Jan-23 8 - 200
Unstoppable Not accepted 23-Jan-23 0 N/A -
Xcapit Fixed 25-Jan-23 7 - -
Zelcore Ack comm, not confirmed 23-Jan-23 N/A N/A -
ZenGo Fixed 24-Jan-23 2 13 -
Zerion Not accepted 23-Jan-23 0 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.

About EIP-712

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

Issue

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.

Attack Vector

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.