Ensure that the delegation signature can't be used as a transaction signature #474

Closed
opened 2023-07-24 21:14:21 +09:00 by davidyuk · 1 comment
davidyuk commented 2023-07-24 21:14:21 +09:00 (Migrated from gitlab.com)

While doing typed data signing in SDK we added a magic number to distinguish its payload from anything else, but I found no such magic number in delegation signature signing.

Most delegation signatures look safe because they include the account address in the payload, except for delegation signature to respond to oracle query. As I understand it is generated as sign(network id + contract address + oracle query id). Without proper validation on the signer side, a malicious actor can get a signature of network id + arbitrary 64 bytes.

Transaction signature can be generated as sign(network id + encoded transaction). The length of the encoded transaction can be increased by adjusting payload, gasLimit fields without behavior changing. So, using a method to sign delegation signature is theoretically possible to generate a transaction signature by crafting a transaction of 64 bytes and splitting it into two pieces ("contract address", "oracle query id").

I didn't spend enough time to find a meaningful example, the closest one is

tx_+D4qAaEBhAyXS5cWR3ZFS6EZ2E7cTWBYqN7JK27cV4qy0wtMQgCCAtOAgwcAA4ZFYFJNsAAAAACBgIQ7msoAgHSE2aw=

it is a 64-byte long ContractCreateTx with empty bytecodes, so it can't be mined.

To protect from attracts like this I suggest adding a mark to ensure that these sign payloads won't overlap. It may be a 0x1a01 prefix in the fashion of https://github.com/aeternity/aepp-sdk-js/pull/1843

While doing typed data signing in SDK we [added a magic number](https://github.com/aeternity/aepp-sdk-js/pull/1843#pullrequestreview-1485132217) to distinguish its payload from anything else, but I found no such magic number in delegation signature signing. Most [delegation signatures](https://docs.aeternity.com/aesophia/v7.2.1/sophia_features/#delegation-signature) look safe because they include the account address in the payload, except for [delegation signature to respond to oracle query](https://github.com/aeternity/aepp-sophia-examples/blob/7798fe789812a74e0afbd4125a81be8468fd5555/test/oracleDelegation.js#L68). As I understand it is generated as `sign(network id + contract address + oracle query id)`. Without proper validation on the signer side, a malicious actor can get a signature of `network id + arbitrary 64 bytes`. Transaction signature can be generated as `sign(network id + encoded transaction)`. The length of the encoded transaction can be increased by adjusting `payload`, `gasLimit` fields without behavior changing. So, using a method to sign delegation signature is theoretically possible to generate a transaction signature by crafting a transaction of 64 bytes and splitting it into two pieces ("contract address", "oracle query id"). I didn't spend enough time to find a meaningful example, the closest one is ``` tx_+D4qAaEBhAyXS5cWR3ZFS6EZ2E7cTWBYqN7JK27cV4qy0wtMQgCCAtOAgwcAA4ZFYFJNsAAAAACBgIQ7msoAgHSE2aw= ``` it is a 64-byte long ContractCreateTx with empty bytecodes, so it can't be mined. To protect from attracts like this I suggest adding a mark to ensure that these sign payloads won't overlap. It may be a 0x1a01 prefix in the fashion of https://github.com/aeternity/aepp-sdk-js/pull/1843
zxq9 commented 2023-08-03 17:40:38 +09:00 (Migrated from gitlab.com)

Created by: hanssv

Good observation!

Though used in Sophia the delegation signatures are just signatures for the sake of the compiler - could you please point this to aeternity repo?

*Created by: hanssv* Good observation! Though used in Sophia the delegation signatures are just signatures for the sake of the compiler - could you please point this to `aeternity` repo?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: QPQ-AG/sophia#474