Ethers.js – How to Prevent Cross-Chain Signed Message Replay

cross-chainethers.jssignature

I'm building a system for Ethereum authentication through the browser, which also checks whether the user owns a specific token.

For this, I'm sending from the back-end a nonce for the user to sign using their private key with Metamask. Then I validate that signature on the back-end to check if it's correct for that address, and whether the user owns said tokens on that address.

Now suppose the token I want to validate is on chain A and chain B. Since the chain is selected simply through Metamask, how do I confirm that the user is on a specific chain, if the signed message is valid on both chains?

From what I was checking it seems like transactions have a different signature across different chains, but not messages.

Best Answer

Transactions have different signatures across different chains because the chainId of the target chain is included in the message. You always sign a transactions for only one chain.

Message signing utilizes the same mechanisms as transaction signing, but message signing doesn't include this kind of extra information. It only includes what you give it to.

So you can include the chainId explicitly inside the message to be signed. And make sure in the receiving end that the chainId is correct. That way it can't be used in a wrong chain.

You may also want to consider including the networkId, although in most cases this is exactly the same as chainId.

Related Topic