Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Case sensitive wallet address chains are not supported by InterchainTokenService #434

Closed
code423n4 opened this issue Jul 21, 2023 · 2 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-323 satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/remote-address-validator/RemoteAddressValidator.sol#L69-L89
https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/interchain-token-service/InterchainTokenService.sol#L707-L724
https://github.com/code-423n4/2023-07-axelar/blob/2f9b234bb8222d5fbe934beafede56bfb4522641/contracts/its/remote-address-validator/RemoteAddressValidator.sol#L133-L138

Vulnerability details

Impact

Case sensitive wallet address chains are not supported by InterchainTokenService

For instance, both P2PKH and P2SH wallet address formats are case-sensitive, so you have to make sure that you're using uppercase and lowercase letters where appropriate. An example of a case-sensitive address is 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2.

It will cause fund loss on bridging to that chain since it will always send messages to the contract address in lowercase format. But since that chain is case sensitive, the contract address in lowercase format is invalid and not found, so the token can't be unlocked on the destination chain and lost forever!

Since Axelar plans to support more chains in the future, there may be some chain whose address is case sensitive

Proof of Concept

RemoteAddressValidator validateSender and addTrustedAddress convert address to lowercase before storing or comparing. This limits the support to only case-insensitive chain

    function validateSender(string calldata sourceChain, string calldata sourceAddress) external view returns (bool) {
        string memory sourceAddressLC = _lowerCase(sourceAddress);
        bytes32 sourceAddressHash = keccak256(bytes(sourceAddressLC));
        if (sourceAddressHash == interchainTokenServiceAddressHash) {
            return true;
        }
        return sourceAddressHash == remoteAddressHashes[sourceChain];
    }

    function addTrustedAddress(string memory chain, string memory addr) public onlyOwner {
        if (bytes(chain).length == 0) revert ZeroStringLength();
        if (bytes(addr).length == 0) revert ZeroStringLength();
        remoteAddressHashes[chain] = keccak256(bytes(_lowerCase(addr)));
        remoteAddresses[chain] = addr;
        emit TrustedAddressAdded(chain, addr);
    }

    function getRemoteAddress(string calldata chainName) external view returns (string memory remoteAddress) {
        remoteAddress = remoteAddresses[chainName];
        if (bytes(remoteAddress).length == 0) {
            remoteAddress = interchainTokenServiceAddress.toString();
        }
    }

On token bridging, it will send message to AxelarGateway with lower case destination address due to string memory destinationAddress = remoteAddressValidator.getRemoteAddress(destinationChain); and remoteAddressValidator.getRemoteAddress returns lowercase address

    function _callContract(
        string calldata destinationChain,
        bytes memory payload,
        uint256 gasValue,
        address refundTo
    ) internal {
        string memory destinationAddress = remoteAddressValidator.getRemoteAddress(destinationChain);
        if (gasValue > 0) {
            gasService.payNativeGasForContractCall{ value: gasValue }(
                address(this),
                destinationChain,
                destinationAddress,
                payload,
                refundTo
            );
        }
        gateway.callContract(destinationChain, destinationAddress, payload);
    }

It will cause fund loss on bridging to that chain since it will always send messages to the contract address in lowercase format. But since that chain is case sensitive, the contract address in lowercase format is invalid and not found, so the token can't be unlocked on the destination chain and lost forever!

Tools Used

Manual review

Recommended Mitigation Steps

Add a map to map if that chain wallet address is case sensitive and don't use _lowerCase on that chain.

Assessed type

Invalid Validation

@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Jul 21, 2023
code423n4 added a commit that referenced this issue Jul 21, 2023
@c4-pre-sort
Copy link

0xSorryNotSorry marked the issue as duplicate of #323

@c4-judge
Copy link

c4-judge commented Sep 1, 2023

berndartmueller marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working duplicate-323 satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants