First Flight #12: Kitty Connect

First Flight #12: Kitty Connect
Beginner FriendlyFoundryNFTGameFi
100 EXP
View results
Submission Details
Severity: high
Valid

`KittyBridge.sol::bridgeNftWithData` doesn't implement access control mechanisms, leading to free mint cross-chain and waste of link funds.

KittyBridge.sol::bridgeNftWithData doesn't implement access control mechanisms, leading to free mint cross-chain and waste of link funds.

  • Description:

    • KittyConnect.sol::bridgeNftToAnotherChain provides a way to transfer NFTs cross-chain through the KittyBridge.sol::bridgeNftWithData function. However, the KittyBridge.sol::bridgeNftWithData doesn't control access, allowing a malicious user to call it directly.

  • Impact:

    • This missimplementation can lead to uncontrolled NFT emission on destination chains and use of all link funds.

  • Proof of Concept:

    Add the code below to `KittyTest.t.sol`
    function testPoCAnyoneCanBridgeNfts() public {
    address sender = makeAddr("sender");
    bytes memory data = abi.encode(makeAddr("catOwner"), "meowdy", "ragdoll", "ipfs://QmbxwGgBGrNdXPm84kqYskmcMT3jrzBN8LzQjixvkz4c62", block.timestamp, partnerA);
    vm.prank(kittyConnectOwner);
    kittyBridge.allowlistSender(networkConfig.router, true);
    vm.prank(sender);
    kittyBridge.bridgeNftWithData(networkConfig.otherChainSelector, sender, data);
    }
  • Recommendation:

    • Implement the onlyKittyConnect modifier to control access.

      Adjust the code as follows
      function bridgeNftWithData(uint64 _destinationChainSelector,
      address _receiver,
      bytes memory _data) external
      + onlyKittyConnect
      onlyAllowlistedDestinationChain(_destinationChainSelector)
      validateReceiver(_receiver)
      returns (bytes32 messageId){
      // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message
      Client.EVM2AnyMessage memory evm2AnyMessage = _buildCCIPMessage(_receiver, _data, address(s_linkToken));
      // Initialize a router client instance to interact with cross-chain router
      IRouterClient router = IRouterClient(this.getRouter());
      // Get the fee required to send the CCIP message
      uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage);
      if (fees > s_linkToken.balanceOf(address(this))) {
      revert KittyBridge__NotEnoughBalance(s_linkToken.balanceOf(address(this)), fees);
      }
      messageId = router.ccipSend(_destinationChainSelector, evm2AnyMessage);
      emit MessageSent(messageId, _destinationChainSelector, _receiver, _data, address(s_linkToken), fees);
      return messageId;
      }
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

`bridgeNftWithData` misses access control

Support

FAQs

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