NFTBridge
60,000 USDC
View results
Submission Details
Severity: low
Invalid

Request Owner Unable to Cancel L1 to L2 Message

Summary

The current implementation of message cancellation functionality in the Starknet blockchain's L1 -> L2 messaging mechanism is flawed. Specifically, the ownership verification required for canceling messages does not correctly authenticate the message sender, thereby preventing message initiators from canceling their own messages as intended.

Vulnerability Details

The vulnerability in the startRequestCancellation() function in Bridge.sol arises from the misuse of the onlyOwner modifier, which restricts cancellation rights to the contract owner rather than the original message sender. This prevents the actual request owner, as specified in the ownerL1 field, from canceling their own request, contrary to Starknet's intended design. This flaw centralizes cancellation authority with the contract owner, potentially leading to abuse, where users are unable to cancel their requests, causing delays or financial losses.

Code Snippet

function startRequestCancellation(
uint256[] memory payload,
uint256 nonce
@> ) external onlyOwner {
IStarknetMessaging(_starknetCoreAddress).startL1ToL2MessageCancellation(
snaddress.unwrap(_starklaneL2Address),
felt252.unwrap(_starklaneL2Selector),
payload,
nonce
);
Request memory req = Protocol.requestDeserialize(payload, 0);
emit CancelRequestStarted(req.hash, block.timestamp);
}

Impact

The request owner cannot cancel his own request, as he should be able to.

Tools Used

Manual review

Recommendations

Make sure that request owner can start cancelation process. For example remove onlyOwner modifier and add:

require(msg.sender == req.ownerL1, "Caller is not the owner of the request");
function startRequestCancellation(
uint256[] memory payload,
uint256 nonce
) external {
// Deserialize the request to extract the ownerL1 field
Request memory req = Protocol.requestDeserialize(payload, 0);
// Ensure the caller is the owner of the request
require(msg.sender == req.ownerL1, "Caller is not the owner of the request");
// Proceed with the cancellation
IStarknetMessaging(_starknetCoreAddress).startL1ToL2MessageCancellation(
snaddress.unwrap(_starklaneL2Address),
felt252.unwrap(_starklaneL2Selector),
payload,
nonce
);
emit CancelRequestStarted(req.hash, block.timestamp);
}
Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Informational / Gas

Please, do not suppose impacts, think about the real impact of the bug and check the CodeHawks documentation to confirm: https://docs.codehawks.com/hawks-auditors/how-to-determine-a-finding-validity A PoC always helps to understand the real impact possible.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.