Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

VRF's request_id is not verified leading to potential replay attack

Summary

fulfillRandomWords() does not verify its input parameter request_id. This could lead to a replay attack where a previous transaction from the VRF coordinator is replayed to influence the random numbers that determine the raffle winner and NFT rarity.

Vulnerability Details

The first call to the VRF coordinator results in a unique request_id. Later, the VRF coordinator calls fulfillRandomWords() with the same request_id as a function argument. It is considered best practice to verify the correct request_id ( https://docs.chain.link/vrf/v2/security#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order , last accessed on 3/14/2024).

Without this check, a previous transaction from the VRF coordinator to the same raffle contract could be replayed. This could be a transaction that was pending in the mempool at one point but got dropped because of a too low gas price, for example, or a transaction that was included in a hard-forked network that allows for cross-chain replay attacks (e.g., Ethereum versus Ethereum Classic).

A malicious user could send such a transaction with known random numbers if they benefit the malicious user before the VRF coordinator could send the transaction with the legitimate request_id.

Impact

Low: According to the specification, the raffle contract is planned to be deployed on Ethereum, Arbitrum, and zksync which have different chain IDs preventing cross-chain replay attacks. However, if there are hard forks of these chains in the future, this replay attack could become possible.

The case of dropped transactions from the VRF coordinator that could be used for a replay attack is rare. A malicious attacker would also have to constantly watch the mempool for such transactions and there is no guarantee that a transaction with suitable random numbers for the attacker would ever occur.

Tools Used

Manual code inspection. VRF documentation ( https://docs.chain.link/vrf/v2/security#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order , last accessed on 3/14/2024).

Recommendations

Store the request_id obtained in request_raffle_winner() as an internal contract variable and compare it against the input argument when fulfillRandomWords() is called with an assert statement.

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.