code-423n4 / 2023-03-zksync-findings

6 stars 1 forks source link

`getBlockHashEVM()` function vulnerability leads to DoS attack #77

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/SystemContext.sol#L73-L79

Vulnerability details

Impact

By using the getBlockHashEVM function with erroneous input, an attacker can take advantage of this vulnerability to deprive the contract of gas and launch a denial of service (DoS) attack against the network, contracts and valid transactions will therefore be hindered or even rendered inaccessible.

Description

The SystemContext contract's getBlockHashEVM() method is used to obtain the hash for a given block number, with a valid block number or range, the function does not verify the input, though the network may be subjected to a denial of service (DoS) attack if an attacker used this vulnerability to request getBlockHashEVM() for an erroneous block number or block range.

Proof of Concept

The vulnerability exists in the contract because it does not validate the input for a valid block number or range before calling blockhash, which returns the hash of the given block.

The line of code that calls blockhash without validation is: https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/SystemContext.sol#L73-L74

A possible exploit scenario is as follows:

Tools Used

Manual Audit

Recommended Mitigation Steps

The getBlockHashEVM() method should be updated to incorporate input validation code. The block number's validity and existence within the blockchain may be verified via the validation code. The function should throw an exception or return a notice if the input is invalid. https://github.com/code-423n4/2023-03-zksync/blob/21d9a364a4a75adfa6f1e038232d8c0f39858a64/contracts/SystemContext.sol#L73-L78

Updated Code:

function getBlockHashEVM(uint256 _block) external view returns (bytes32 hash) {
    require(_block <= block.number, "Block number is invalid");
    require(block.number - _block <= 256, "Block number is too far in the past");
    hash = blockHash[_block];
}
GalloDaSballo commented 1 year ago
Screenshot 2023-03-20 at 10 08 50
c4-judge commented 1 year ago

GalloDaSballo marked the issue as unsatisfactory: Invalid