Solidity Attack Vectors: #5 - Denial Of Service With Block Stuffing
Block stuffing is a type of attack in which an attacker floods the network with many transactions, making it difficult for legitimate transactions to be processed. In this article, we will learn about how block-stuffing attacks work.
What Is A DoS Attack?
A denial of service attack is a type of cyber attack in which an attacker attempts to disrupt the normal operation of a network by overwhelming it with traffic or requests, and making it unavailable to its intended users.
"Block That Stuff: How Attackers Use Block Stuffing to Exploit Smart Contracts"
Have you ever wondered why someone would want to stuff a block, or how they go about doing it? If a reward system is in place, there will always be greedy attackers who want to exploit it. Now, let's take it to a smart contract level. If you have a reward system smart contract that rewards users based on certain predefined conditions or time factors, an attacker may be able to exploit this by participating in your contract and then blocking other users from doing the same by "preventing their transactions from being included in a block until the predefined conditions are met"
, allowing the attacker to claim the reward.
Preventing Transactions From Being Included in a Block
In Ethereum, the use of gas and gas fees helps prevent network congestion by limiting the amount of computational work that can be done on the network. Ethereum has implemented several measures to achieve this, including gas, gas fees, and the block gas limit. However, an attacker can also use this to prevent normal users from using the network. They can do this by performing a transaction that uses almost or all of the block gas limit and then forcing a transaction to be added to the next block instead of the current one, if the next block is not full.This process can continue until the attacker has used up all of their resources.
Generally, these types of attacks involve an attacker sending a large number of transactions or executing a smart contract with a lot of computational work in order to consume the block gas limit and prevent other transactions from being included in the block.
Consider this smart contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Rewarder {
address payable beneficiary;
uint256 endRegistrationTime;
constructor(uint256 _endRegistrationTime) {
endRegistrationTime = _endRegistrationTime;
}
function register() external {
require(block.timestamp <= endRegistrationTime);
beneficiary = payable(msg.sender);
}
function rewardBeneficiary() external {
require(block.timestamp >= endRegistrationTime);
beneficiary.transfer(address(this).balance);
}
}
The "Rewarder" smart contract has two state variables: "beneficiary", which holds the address of the recipient of the reward, and "endRegistrationTime", which holds the time limit for registration. The logic of this contract is simple: users can call the "register" function to save their address as the "beneficiary", but other users can override the previous "beneficiary" by calling the "register" function again. This process continues until the "endRegistrationTime" limit is reached, at which point the "rewardBeneficiary" function can be called and the final "beneficiary" address is sent the contract balance.
If an attacker sees a contract like this and wants to participate in the reward system, they can register their address and prevent other users from doing so until the "endRegistrationTime" has expired. They can do this by creating another smart contract with a large amount of computational work on the blockchain, which would use a lot of gas and consume most of the block gas limit. This would prevent other users from being able to register their address and would allow the attacker to be the only one to receive the reward.
The block gas limit of Ethereum is typically around 30 million. If an attacker's contract uses a large portion of this amount, only a few additional transactions can be added to the block, assuming that the "register" function requires a large amount of gas.
How To Prevent This
When it comes to block stuffing attacks, there are not many ways to prevent them since the attacks do not originate from the smart contract itself. One possible solution is to use a whitelisting method if necessary. By verifying users off-chain, you can ensure that only trusted parties can be added to the whitelist and allowed to register for the reward. This helps with easy monitoring and you can simply remove a malicious address from the whitelist. However, it is important to note that no solution is foolproof and it is always possible for an attacker to find a way to disrupt the network.
Conclusion
In conclusion, some parties may be willing to go to great lengths to exploit reward systems. In some cases, this may not be necessary or worth the effort because the attacker may end up spending more on the attack than they would gain from it