본문 바로가기

자주나오는패턴

[Common Vulnerabilities] Reentrancy

재진입 공격(또는 재귀 호출 공격)에서는 악의적인 컨트랙트가 첫 번째 함수 호출이 끝나기 전에 호출한 컨트랙트로 다시 호출한다. 이로 인해 함수의 다른 호출들이 바람직하지 않은 방식으로 상호 작용할 수 있다. 그것을 방지하기 위해서 reentrancy를 예방하는 법을 알아야 한다. 

 

1. Checks-Effects-Interactions 패턴사용

2. Openzeppelin reentrancyGuard컨트랙트 사용

 

1번은 CEI pettern이라고도 부르는데 

function auctionEnd() public { 
  // 1. Checks require(now >= auctionEnd); 
  require(!ended); 
  // 2. Effects 
  ended = true; 
  // 3. Interaction 
  beneficiary.transfer(highestBid); 
}

이런식으로 하라는 얘기다. 우선 조건을 먼저 살피고, 그다음에 상태를 변경하고, 그다음 interaction을 하라는 것.

 

2번은 OZ에 있는 ReentrancyGuard를 이용하는 것.

    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

 

 

 

 

[ 참고 및 추가자료 ]

1. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol
2. https://medium.com/returnvalues/smart-contract-security-patterns-79e03b5a1659

3. https://docs.soliditylang.org/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern

4. https://swcregistry.io/docs/SWC-107/