stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: medium
Invalid

Sender validation loophole in CCIP logic risks fund drain and disruption.

Summary

Lack of thorough sender validation in the CCIP message handling logic. This presents a risk of unauthorized accounts submitting fake cross-chain messages to manipulate contract state.

Vulnerability Details

The functions that process CCIP messages are: SDLPoolCCIPController.ccipReceive
SDLPoolCCIPController._verifyCCIPSender

function ccipReceive(Client.Any2EVMMessage calldata _message) external override onlyRouter {
_verifyCCIPSender(_message);
if (_message.destTokenAmounts.length == 1 && _message.destTokenAmounts[0].token == address(sdlToken)) {
IRESDLTokenBridge(reSDLTokenBridge).ccipReceive(_message);
} else {
_ccipReceive(_message);
}
}
function _verifyCCIPSender(Client.Any2EVMMessage memory _message) internal view virtual;
}

However, _verifyCCIPSender() only checks: SDLPoolCCIPControllerPrimary.Line 376

if (sender != whitelistedDestinations[sourceChainSelector]) revert SenderNotAuthorized();

It compares the sender to a whitelist based on the source chain. But there are no checks that:

  • The source chain ID itself is valid

  • The sender is an authorized CCIP router on that chain

This leaves open the possibility for an attacker to:

  1. Specify any fake source chain ID

  2. Set themselves as the sender

  3. Bypass the whitelist check since the chain is made up

  4. Submit arbitrary state-changing messages to the pool

Impact

To exploit this, an attacker could:

  • Drain funds by sending fake transfer messages

  • Manipulate balances by sending fake deposit/withdrawal notifications

  • Disrupt operations by sending conflicting or reversing messages

Tools Used

Vs

Recommendations

More robust sender validation is needed in _verifyCCIPSender():

// Check source chain is in known/authorized list
if (!validSourceChains[sourceChainSelector])
revert InvalidSourceChain();
// Verify sender signature over the full CCIP message
if (!ECDSA.recover(CCIPUtils.hashMessage(message), signature) == routerAddressOnChain[sourceChainSelector])
revert InvalidSender();

This would prevent fake or unauthorized messages from being accepted.

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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