ERC721 NFT 콘트랙트는 NFT 전송을 위한 두 가지 옵션, transferFrom과 safeTransferFrom을 제공합니다. transferFrom보다 safeTransferFrom이 더 안전한지 궁금할 수 있습니다. 대답은 '그렇다'와 '아니다'입니다. 자세히 살펴보겠습니다:
safeTransferFrom의안전성: 이 메서드에는 수신자가 ERC721 NFT를 올바르게 처리할 수 있는지 확인하는 절차가 포함되어 있습니다. 즉, 수신자가 필요한 NFT 처리 기능이 없는 컨트랙트인 경우 NFT가 "고착"될 가능성이 적습니다.안전 주의:
안전 전송은NFT 자체에 대한 안전장치를 제공하지만,트랜잭션의안전을 보장하지는 않습니다. 오히려 재진입 공격에 취약할 수 있습니다. 이는 수신자가 다른 컨트랙트인 경우 수신자 컨트랙트의 함수를 트리거하기 때문입니다.
실제 사례를 살펴보겠습니다. 2024년 1월 25일, 한 공격자가 NBLGAME 컨트랙트의 재진입 취약점을 악용했습니다. 익스플로잇된 자금의 총 가치는 약 18만 달러로 추정됩니다.
개요
Attacker : https://optimistic.etherscan.io/address/0x1fd0a6a5e232eeba8020a40535ad07013ec4ef12 Attack Contract : https://optimistic.etherscan.io/address/0xe4d41bdd6459198b33cc795ff280cee02d91087b Vulnerable Contract : https://optimistic.etherscan.io/address/0x5499178919c79086fd580d6c5f332a4253244d91 Attack TX: https://optimistic.etherscan.io/tx/0xf4fc3b638f1a377cf22b729199a9aeb27fc62fe2983a65c4d14b99ee5c5b2328
익스플로잇 분석
익스플로잇된 취약점은 NFT를 반환할 때 safeTransferFrom을 사용함에 따른 출금Nft 함수의 재진입 취약성에서 비롯되었습니다.
공격자는 먼저 NFT를 예치한 다음 컨트랙트에 NBL 토큰을 스테이킹했습니다. NFT를 반환하는 동안 컨트랙트는 NFT를 먼저 돌려보낸 다음 나중에 스테이킹된 토큰을 반환합니다. 안전한 전송이 공격자의 컨트랙트의 onERC721Received 함수를 트리거하므로 공격자에게는 기회가 있었습니다. 스테이킹된 NBL 금액이 아직 차감되지 않았기 때문에 컨트랙트의 상태가 일관되지 않았습니다. 이때 공격자는 스테이킹된 NBL의 양이 금액으로 저장되어 있기 때문에 ERC721Received를 활용하여 NFT를 인출하기 위한 재진입 호출을 시작하여 효과적으로 NFT를 계약에 다시 재예치하여 다시 NFT를 인출하기 위해 호출했습니다.
두 번째 인출은 스테이킹된 NBL 토큰을 성공적으로 회수했습니다. 그 후, 첫 번째 출금에서도 이전에 저장된 금액에서 NBL 토큰이 차감되었지만 재입금으로 인해 그대로 유지되었습니다. 익스플로잇은 성공했고 공격자는 스테이킹된 토큰의 두 배를 받았습니다.
결론
ERC721 NFT 스마트 컨트랙트로 작업할 때는 항상 수신자의 ERC721Received에서 safeTransferFrom 함수가 트리거되어 재진입에 취약할 수 있다는 점에 유의하시기 바랍니다. 이 위험을 완화하는 두 가지 효과적인 방법은 다음과 같습니다:
확인-효과-상호 작용 패턴: 이 패턴은 외부 호출이 이루어지기 전에 컨트랙트의 상태 변수를 업데이트하는 것을 강조합니다. 이렇게 하면 공격자가 외부 호출 중에 컨트랙트의 상태를 조작하지 못하도록 방지할 수 있습니다.
재진입 가드: 모든 공개/외부 함수에서
재진입 가드 메커니즘을 사용하는 것을 고려하세요. 이렇게 하면 초기 호출이 완료되기 전에 함수가 다시 입력되지 않도록 하는 수정자가 추가됩니다.
보안을 극대화하려면 가능한 한 두 가지 방법을 모두 컨트랙트에 적용하는 것이 좋습니다. 재진입 가드는 약간의 가스 비용이 발생하지만, 재진입 공격에 대한 추가적인 보호 계층을 제공합니다.
베리체인을 읽어주셔서 감사합니다! 무료로 구독하여 새로운 포스팅을 받아보고 제 작업을 응원해 주세요.






