🔐
Secure Coding Handbook
  • Secure Coding Handbook
  • Resources
  • Client side
    • Cross-Site Scripting [XSS]
    • Cross-Site Request Forgery [CSRF]
    • Clickjacking
    • Open Redirects
  • Server Side
    • SQL Injections [SQLi]
    • XML External Entity Injection [XXE]
    • OS Command Injection [Command Execution]
    • File Upload
    • Server-Side Request Forgery [SSRF]
    • Host Header Injection
    • Authentication
    • Directory Traversal
    • Template Injection [SSTI]
  • API
    • Broken Object Level Authorization
    • Excessive Data Exposure
    • Mass Assignment
  • Auxiliary
    • Vulnerable Dependency Management
    • Deserialization
    • Logging
  • Solidity
    • Re-Entrancy
Powered by GitBook
On this page
  • 1. Introduction:
  • 2. Typical vulnerable code:
  • 3. Mitigations:
  • 3.1. Checks-Effects-Interactions.
  • 3.2. Implementing a guard.
  • 4. Takeaways:

Was this helpful?

  1. Solidity

Re-Entrancy

PreviousLogging

Last updated 3 years ago

Was this helpful?

1. Introduction:

Re-Entrancy allows an attacker to recursively call a function from a vulnerable contract, to whatever malicious intent they have. (usually, we're talking about completely draining the vulnerable contract's balance)To learn about DAO's hack(the "historical" origin of this vulnerability)

As usual, we will not showcase the actual exploit of the vulnerable contract.

2. Typical vulnerable code:

VulnerableContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract VulnerableContract {
  
  mapping(address => uint) public balances;

  function sendTo(address _to) public payable {
    balances[_to] += msg.value ;
  }

  function balanceOf(address _who) public view returns (uint balance) {
    return balances[_who];
  }

  function withdraw(uint _amount) public {
    if(balances[msg.sender] >= _amount) {
      // the amount is sent to the caller of the contract. 
      (bool result,) = msg.sender.call.value(_amount)("");
      if(result) {
        _amount;
      }
      // balance gets updated after VulnerableContract sends the _amount.
      balances[msg.sender] -= _amount;
    }
  }

  receive() external payable {}
}

3. Mitigations:

3.1. Checks-Effects-Interactions.

The Checks-Effects-Interactions pattern is essentially a way of organizing statements such that the state of the contract is updated consistently before actually interacting with other contracts/ addresses. By placing effects(eg. decreasing the user balance) before interactions(eg. sending eth to the user), we ensure that all state changes are done before any potential reentrancy point, leaving the state of the contract consistent on each call/ interaction.

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract VulnerableContract {
  
  mapping(address => uint) public balances;

  function sendTo(address _to) public payable {
    balances[_to] += msg.value ;
  }

  function balanceOf(address _who) public view returns (uint balance) {
    return balances[_who];
  }

  function withdraw(uint _amount) public {
    if(balances[msg.sender] >= _amount) {
      // updating the balance before sending the _amount
      balances[msg.sender] -= _amount;
      (bool result,) = msg.sender.call.value(_amount)("");
      if(result) {
        _amount;
      }
      
    }
  }

  receive() external payable {}
}

3.2. Implementing a guard.

4. Takeaways:

It’s essential to program our contracts to be safe against reentrancy by organizing code according to the checks-effects-interactions pattern. Moreover, it is important to consider using already available solutions, such as the ones provided by OpenZeppelin, in order to properly mitigate the risk against such attacks.

You can find more details about this topic here:

The issue is found on line 26. Since the balances[] of the sender is not updated properly(before actually sending the money to the msg.sender) an attacker can recursively call the withdraw function. For more details on how this exploit works, from the attacker's perspective, .

Making use of a reentrant guard, .

check out this post.
For that, you may find this video useful.
you can watch this cool video
such as this one
Re-entrancy after Istanbul.
Reentrancy | Hack Solidity
Solidity By Example | Re-entrancy