Insufficient Gas Griefing Attack
Failed meta-transactions with insufficient gas leave the nonce unchanged, allowing the same signed payload to be replayed and exposing the contract to denial of service and replay attacks.
Description
The NativeMetaTransaction contract demonstrates vulnerability to Insufficient Gas Griefing Attacks. In this vulnerability, an attacker can initiate transactions with insufficient gas, causing the transaction to fail after consuming the gas, which may lead to various risks including replay attacks.
Specifically, the contract fails to handle transactions where the gas provided is not enough to cover the transaction's completion. With the nonces only incrementing after the require(verify(...), "Signer and signature do not match") statement, failed transactions due to out-of-gas errors do not revert the nonce, leaving the contract open to potential replay attacks.
Impact
- Transaction Failure: Deliberately sending transactions with insufficient gas can cause transaction failure, wasting the gas used and causing disruption to the contract's operation.
- Replay Attacks: Since nonces do not revert upon transaction failure due to out-of-gas errors, this allows for potential replay attacks. An attacker can use the same nonce with a different transaction, leading to unauthorized or unintended transactions being executed.
- Denial of Service (DoS): Persistent transaction failures can lead to a denial-of-service scenario where legitimate users cannot successfully interact with the contract.
For reference: Code4rena Rolla finding H-04.
Recommendation
To protect the contract against Insufficient Gas Griefing Attacks, consider the following mitigation measures:
- Gas Checks: Implement mechanisms to check if the transactions are supplied with sufficient gas, and reject those that do not meet the minimum required gas.
- Enhanced Nonce Management: Consider deploying enhanced nonce management mechanisms to ensure that nonces of failed transactions are handled securely, preventing potential replay attacks. This could involve invalidating the nonces of failed transactions or implementing a more secure nonce generation and validation method.
Consider adding the following verification between require and return lines of executeMetaTransaction:
if (gasleft() <= req.gas / 63) {assembly {invalid()}}

