Infinite Loop Griefing Attack
Report ID
#24548
Report type
Smart Contract
Has PoC?
Yes
Target
Impacts
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Unbounded gas consumption
- Temporary freezing of funds for at least 1 hour
Bug Description
Good Day Operations,
Apologies my last submission was not impact specific.
I hope you view my persistence to get these bugs fixed as my ongoing commitment to the safety of your protocol as a security researcher.
The closest medium attack according to Immunefi impact in scope is:
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Unbounded gas consumption
- Even a high of Temporary freezing of funds for at least 1 hour
With that context:
- I created a Malicious ERC20 with unbounded loop
Attack:
- Attacker calls beanstalk with malicious token with external to internal mode
beanstalk.transferToken(address(FakeToken), address(attacker), 10_000_000e6, 0, 1);
- beanstalk safeTransferFrom() calls attacker fake ERC20 token transferFrom()
- fake ERC20 token transferFrom includes an unbounded loop that calls back into bean with real bean token with 0 value
beanstalk.transferToken(address(bean), address(attacker), 0, 0, 1);
- Contract is stuck in an unbounded loop
For sake of clarity this is the simplest unbouded loop. There are other more complex variations but its to proof the point.
while (true) {
// Code inside the loop (e.g., modifying state variables).
}
If tokenFacet is responsible for gas it can lead to additional unbounded gas consumption If original caller is responsible for gas with, sufficient gas attacker can Temporary freezing of funds for at least 1 hour
Impact
As mentioned earlier the following impacts are possible:
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
- Unbounded gas consumption
- Even a high of Temporary freezing of funds for at least 1 hour
Risk Breakdown
Difficulty to Exploit: Easy Weakness: CVSS2 Score:
Recommendation
- validate erc20 token submitted to tokenTransfer()
- create non-reentrant modifier for tokenTransfer()
Proof of concept
- mkdir beanPOC
- forge init
- delete default Counter.sol and Counter.t.sol
- insert beanLoop.sol and interfaces.sol into src folder
run with forge test --contracts ./src/beanLoop.sol -vv
All the best with your analysis
BIC Response
This is not a valid bug report because the described attack does not lead to any of the listed impacts. The only user that can be griefed is the user of the "malicious" ERC-20 contract.
For example, the following statement:
If tokenFacet is responsible for gas it can lead to additional unbounded gas consumption If original caller is responsible for gas with, sufficient gas attacker can Temporary freezing of funds for at least 1 hour
... does not make sense, as only the user who calls transferFrom
on the "malicious" token would be paying for gas (i.e., they'd grief themselves).
Due to these reasons, we are closing the submission and no reward will be issued.