EthereumCasts icon indicating copy to clipboard operation
EthereumCasts copied to clipboard

Reentry attack vulnerability in Campaign.sol

Open sergeny opened this issue 6 years ago • 3 comments

   function finalizeRequest(uint index) public restricted {
        Request storage request = requests[index];

        require(request.approvalCount > (approversCount / 2));
        require(!request.complete);

        request.recipient.transfer(request.value);
        request.complete = true;
    }

When we are sending money to the recipient, nothing prevents a second recursive call to finalizeRequest. Even though the function is restricted, the recipient could pass control to the manager, who would then execute a recursive call. In this way, the manager, in cooperation with a vendor, could get an approval for a small amount, but withdraw many times that amount.

Technically, it would a solution to check that manager is a human and not a smart contract, but no such check is being done. Furthermore, one could make an innocent-looking smart contract, pretending it's just a convenience tool for the manager, in case someone decides to look, but keep it upgradable to leave a backdoor.

Update: the proposed solution is to interchange the last two lines, setting the flag to true before doing the transfer.

sergeny avatar Aug 03 '18 04:08 sergeny

Just wondering what exactly was the fix?

JuiceyDuecy avatar Aug 03 '18 04:08 JuiceyDuecy

Git diff I guess

JuiceyDuecy avatar Aug 03 '18 04:08 JuiceyDuecy

You could swap the last two lines, setting complete to true before doing the transfer.

sergeny avatar Aug 03 '18 04:08 sergeny