Boost _ Folks Finance 34150 - [Smart Contract - Low] Failed messages never expire and can be replaye
Submitted on Tue Aug 06 2024 02:16:38 GMT-0400 (Atlantic Standard Time) by @JCN2023 for Boost | Folks Finance
Report ID: #34150
Report type: Smart Contract
Report severity: Low
Target: https://testnet.snowtrace.io/address/0xa9491a1f4f058832e5742b76eE3f1F1fD7bb6837
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
Description
Bug Description
When a user's transaction fails on the Hub chain, it will be stored as a failed message in the BridgeRouter:
127: function receiveMessage(Messages.MessageReceived memory message) external payable override {
...
115: // call handler with received payload
116: try BridgeMessenger(handler).receiveMessage(message) {
117: // emit message received as suceeded
118: emit MessageSucceeded(adapterId, message.messageId);
119: } catch (bytes memory err) {
120: // don't revert so GMP doesn't revert
121: // store and emit message received as failed
122: failedMessages[adapterId][message.messageId] = message; // store failed message
123: emit MessageFailed(adapterId, message.messageId, err);The message can then be retried at anytime via the same BridgeRouter:
As we can see above, the msg.sender of the retryMessage transactions is not validated. Therefore, anyone is able to retry a failed message at anytime.
Impact
Bad actors can retry user's old, failed messages. This will allow the user's loan to potentially be manipulated without their knowledge. For example, an old withdraw or borrow transaction can be retried, forcing the user to redeposit their collateral or repay their unexpected borrow position. Failed messages would likely be a result of user error, but can also be temporal (cap reached). In these cases, users may opt to simply submit a new transaction with more optimal arguments in order to have a successful tx.
The conditions of this exploit requires users to have old failed messages that were never retried. Additionally, the failed message is not guaranteed to succeed at any future time. Based on these pre-conditions, I have chosen to mark the severity of this report as low.
Recommended Mitigation
I would recommend decoding the message.payload during the retryMessage transaction and validating that the msg.sender is an authorized address for the accountId of the message.
Proof of concept
Proof of Concept
To run foundry POC:
add test file to
test/directory of a foundry repoadd
AVAX_FUJI_RPC_URLvariable as environment var or in.envfilerun test with
forge test --mc FolksPOC_GriefUserByFailedTransaction
Last updated
Was this helpful?