avoid replay attacks on signing on smart contracts

by js wang   Last Updated November 05, 2018 09:28 AM

the scenario: a user has a privatekey and wants to sign something to send to the contract ex: the user send his (message,signature,publickey) to the contract and the contract can verify it with the arguments user provided and recorded it. But in this situation, when the record on the contract is (message,signature,publickey) an attacker can write arguments previous send by the user to overwrite present data, cause is signed by the user before the contract will verify it and record it on the contract

My question is that are there any chances that without adding another data structure like a counter (record on the contract and be part of the signature, i.e make the data to (msg,sig,pub,counter)) to avoid this kind of replay attack?

Answers 3

I think it is important to note that a signature is unique to the message content.

If I send a "signed message" (message + signature), and then someone changes my message content, then the signature will no longer be valid. Thus the entire signed message will not be valid.

Let me know if this is not the scenario you are interested in.

Shawn Tabrizi
Shawn Tabrizi
November 05, 2018 09:22 AM

One a user makes a transaction to a contract the transaction is signed. Just checking msg.sender verify that whoever sent the transaction is in control of the private key.

Yet assuming that for some reason the user has to sign a message and send it, the attack can be avoided by requiring that the sender of the message is the one signing it, that is you check that msg.sender equals to the output of the verification of the signature (ecrecover).

Hope this helps

November 05, 2018 09:24 AM

The signature only signs a specific message, so you can't use the same signature for a different message.

There is a class of attacks called replay attacks which apply to resending the same message when the user did not intend it. This can be discussed with regard to signing Ethereum transactions, or with regard to custom signing schemes created by contracts with the signed data passed as data.

For Ethereum transactions there is already a counter included in the signed data to handle exactly this problem, called the nonce.

If you're designing a custom signing scheme for a contract, you may well need to include some data to prevent transactions being replayed. The obvious solution is to add a nonce and keep track of each account's last nonce in contract storage. Alternatively you could store the actual hash of the signed message and refuse to accept the same message twice. However, this is not necessary in all cases, as for some contracts the message would only be applicable to a particular contract state, and would result in a revert if applied to an old contract state in any case, in which case the transaction could not be successfully replayed.

PS. In Ethereum it is not normally necessary to pass an argument for the pubkey, as this can be recovered from the signature.

Edmund Edgar
Edmund Edgar
November 05, 2018 09:25 AM

Related Questions

What replay attack protections does Ropsten provide?

Updated November 28, 2017 06:28 AM