Skip to content

Committed UTxOs at Commit validator and UTxOs at Initial validator can be spent arbitrarily by anyone

Critical
Unknown published GHSA-6x9v-7x5r-w8w6 Oct 4, 2023

Package

hydra-plutus

Affected versions

< 0.12.0

Patched versions

0.12.0

Description

Summary

Users send the UTxOs they wish to commit into the Hydra head first to the commit validator, where they remain until they are either collected into the head validator or the protocol initialisation is aborted and the value in the committed UTxOs is returned to the users who committed them.

The commit validator contains a flawed check when the ViaAbort redeemer is used, which allows any user to spend any UTxO which is at the validator arbitrarily, meaning an attacker can steal the funds that users are trying to commit into the head validator. The intended behaviour is that the funds must be returned to the user which committed the funds and can only be performed by a participant of the head.

The initial validator also is similarly affected as the same flawed check is performed for the ViaAbort redeemer.

Details

UTxOs at the commit validator can be spent with either the ViaAbort redeemer, used when the protocol initialisation is being aborted, or the ViaCollectCom redeemer, used when all the parties committed UTxOs are being collected into the head validator.

The commit validator performs a single check when the ViaAbort redeemer is used: check that the head ID state token is burnt. The intention of this check is that if we ensure the head state token is burnt, then the transaction must also spend an input at the head validator with the Abort redeemer, and the head validator will have performed the checks that the committed value is returned to the user which committed.

https://github.com/input-output-hk/hydra/blob/master/hydra-plutus/src/Hydra/Contract/Commit.hs#L94-L97

The check that the ST is burned is done via the mustBurnST function.

https://github.com/input-output-hk/hydra/blob/master/hydra-plutus/src/Hydra/Contract/Util.hs#L32-L42

This function likely should only return True if the txmint field contains headCurrencySymbol -> "HydraHeadV1" -> (-1), but on line 37 it returns True if no token kinds of the headCurrencySymbol are found in the txmint field, and on line 40 it returns True if some tokens kinds of headCurrencySymbol are found in the txmint field but no token named "HydraHeadV1" is found. This check currently will return True if the txmint field contains no entries.

This means the commit validator will execute successfully when using the ViaAbort redeemer without needing to burn the ST token, which means we can avoid executing the head validator and therefore avoid executing the checks which ensure the funds in the committed UTxOs are returned to the correct owners.

The initial validator also is affected as the same check using mustBurnST is performed for the ViaAbort redeemer, but the impact is lesser because there should not be significant funds at the initial validator. The impact for the initial validator is more like denial of service, because an attacker could prevent a Hydra head from being successfully created because they can abort any head which is in the process of being initialised, despite them not needing to being a participant of the head.

PoC

Setup:

  • A user has sent a UTxO to the commit validator.

Then, create a transaction with the properties:

  • Spend a UTxO at the commit validator as an input, using the ViaAbort redeemer
  • Leave the txmint field empty
  • Create any output such that the preservation of value rule is maintained (for example send the funds from the UTxO at the commit validator to any address you choose)

Impact

Critical

An attacker can steal any funds that user's try to commit into a Hydra head. Also, an attacker can prevent any Hydra head from being successfully opened.

It does not allow an attacker to take funds which have been successfully collected into and currently reside in the head validator.

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H

CVE ID

CVE-2023-38701

Weaknesses

No CWEs

Credits