Summary
Not including a unique head identifier in the multi-signatures, allows an attacker to replay old signatures to close or contest a head with a wrong or incompatible head state.
Details
In the Hydra HeadV1 protocol, all parties do sign snapshots off-chain. The snapshots themselves only include the new UTxO state and a list of transactions which led to that state. Such a "signed snapshot" can then be used as a certificate $\xi$ to close the head or contest a state of a closed head on the main chain.
For that the close & contest validators do check $\mathsf{MSVerify}(\tilde{k}_H, \mathsf{msg}, \xi) = \mathsf{true}$ where the signed message is $\mathsf{msg} = (\mathsf{cid}, \eta_0, \eta)$ where $\eta = (sn, U^{\#})$.
The current implementation, however, does only sign $\eta$ and neither incorporate $\mathsf{cid}$ nor $\eta_0$ with the following impact:
- Not sign $\mathsf{cid}$: Signatures of the same participants, but from different heads can be re-used or re-played. (Scope of this advisory)
- Not sign $\eta_0$: Signatures of an open head can be re-used in case the main chain roll-backs "past open" and a different commit transaction leads to the head opening. (Out of scope, much harder to mount an attack)
The on-chain verification of the snapshot signature is here
The off-chain signing of a snapshot is here where the signable representation decides on the actual bytes signed.
Impact
Not signing and verifying $\mathsf{cid}$ allows an attacker (which must be a participant of this head) to use a snapshot from an old head instance with the same participants to close the head or contest the state with it.
This can lead to an incorrect distribution of value (= value extraction attack; hard, but possible) or prevent the head to finalize because the value available is not consistent with the closed utxo state (= denial of service; easy).
Workaround
Rotate keys between heads so not to re-use keys and not result in the same multi-signature participants.
Summary
Not including a unique head identifier in the multi-signatures, allows an attacker to replay old signatures to close or contest a head with a wrong or incompatible head state.
Details
In the Hydra HeadV1 protocol, all parties do sign snapshots off-chain. The snapshots themselves only include the new UTxO state and a list of transactions which led to that state. Such a "signed snapshot" can then be used as a certificate$\xi$ to close the head or contest a state of a closed head on the main chain.
For that the close & contest validators do check$\mathsf{MSVerify}(\tilde{k}_H, \mathsf{msg}, \xi) = \mathsf{true}$ where the signed message is $\mathsf{msg} = (\mathsf{cid}, \eta_0, \eta)$ where $\eta = (sn, U^{\#})$ .
The current implementation, however, does only sign$\eta$ and neither incorporate $\mathsf{cid}$ nor $\eta_0$ with the following impact:
The on-chain verification of the snapshot signature is here
The off-chain signing of a snapshot is here where the signable representation decides on the actual bytes signed.
Impact
Not signing and verifying$\mathsf{cid}$ allows an attacker (which must be a participant of this head) to use a snapshot from an old head instance with the same participants to close the head or contest the state with it.
This can lead to an incorrect distribution of value (= value extraction attack; hard, but possible) or prevent the head to finalize because the value available is not consistent with the closed utxo state (= denial of service; easy).
Workaround
Rotate keys between heads so not to re-use keys and not result in the same multi-signature participants.