Last updated: March 11, 2025
SCWE-034: Insecure Cross-Chain Messaging
Stable Version v0.0.1
This content is in the version-(v0.0.1) and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).
Send Feedback
Relationships
Description
Insecure cross-chain messaging refers to vulnerabilities that arise when communicating between different blockchains. This can lead to:
- Unauthorized actions by malicious actors.
- Loss of funds or data.
- Exploitation of vulnerabilities in cross-chain logic.
- Validate messages: Ensure all cross-chain messages are properly validated.
- Use secure protocols: Leverage secure cross-chain communication protocols.
- Test thoroughly: Conduct extensive testing to ensure cross-chain logic is secure.
Examples
- Insecure Cross-Chain Messaging
pragma solidity ^0.8.0;
contract InsecureCrossChain {
event MessageProcessed(bytes message);
function processMessage(bytes memory message) public {
// β No validation of the sender (anyone can call this function!)
// β No signature verification (attackers can inject fake messages!)
// π¨ No relayer authorization
// π¨ No replay protection
emit MessageProcessed(message);
}
}
π΄ Issue: The function accepts messages without validation, allowing unauthorized transactions.
Unauthorized Relayers (Anyone Can Call!)
- Issue: The function allows any msg.sender to call processMessage(), meaning an attacker can send arbitrary messages.
- Impact: Attackers can forge transactions, trigger unintended actions, or drain funds if the function is connected to cross-chain asset transfers.
No Signature Verification (Fake Messages)
- Issue: The contract doesnβt verify the authenticity of the message.
- Impact: Attackers can inject fake messages and trick the contract into executing unauthorized actions.
Replay Attacks
- Issue: The contract doesnβt track processed messages.
- Impact: The same message can be replayed multiple times, leading to repeated execution of sensitive operations.
- Secure Cross-Chain Messaging
pragma solidity ^0.8.0;
contract SecureCrossChain {
mapping(address => bool) public trustedRelayers;
mapping(bytes32 => bool) public processedMessages;
event MessageProcessed(bytes32 indexed messageHash, address indexed sender);
event RelayerUpdated(address relayer, bool status);
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not the owner");
_;
}
constructor(address[] memory initialRelayers) {
owner = msg.sender;
for (uint i = 0; i < initialRelayers.length; i++) {
trustedRelayers[initialRelayers[i]] = true;
}
}
function setRelayer(address relayer, bool status) external onlyOwner {
trustedRelayers[relayer] = status;
emit RelayerUpdated(relayer, status);
}
function processMessage(
bytes memory message,
uint8 v, bytes32 r, bytes32 s
) public {
require(trustedRelayers[msg.sender], "Unauthorized relayer");
bytes32 messageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(message)));
address signer = ecrecover(messageHash, v, r, s);
require(signer != address(0), "Invalid signature");
require(!processedMessages[messageHash], "Message already processed");
processedMessages[messageHash] = true;
emit MessageProcessed(messageHash, signer);
// β
Securely process the message
}
}
Fix: Implements signature verification, relayer validation, and replay protection.
Why is this better?
β
Verifies Signatures Properly: Uses ecrecover() with Ethereum Signed Message hashing.
β
Admin Can Manage Relayers: Allows dynamic relayer updates via setRelayer().
β
Prevents Replay Attacks: Tracks processed messages in processedMessages mapping.
β
Ensures Message Authenticity: Only validly signed messages are accepted.