본문 바로가기
유익한정보 유익한정보

스마트 컨트랙트의 재진입(Reentrancy) 취약점이 발생하는 구조

heanajiser 읽는 시간 약 8분
스마트 컨트랙트의 재진입(Reentrancy) 취약점이 발생하는 구조

스마트 컨트랙트의 재진입 취약점은 외부 컨트랙트가 호출될 때, 원래의 함수 실행이 끝나기 전에 공격자가 동일한 함수를 다시 호출하면서 발생합니다. 특히 이더리움과 같은 환경에서 출금 함수가 잔액을 업데이트하기 전에 외부로 자금을 먼저 전송할 때 문제가 생깁니다. 공격자는 이 틈을 타 잔액이 차감되기 전 반복적으로 출금을 시도하여 컨트랙트의 자금을 고갈시킬 수 있습니다. 이를 방지하려면 상태 변수를 먼저 변경하거나 뮤텍스 패턴을 활용해 재진입을 원천 차단하는 설계가 필수적입니다. 단순히 코드를 작성하는 것을 넘어, 자산의 흐름과 상태 변화의 순서를 꼼꼼히 따지는 보안 중심의 개발 습관이 무엇보다 중요합니다.

스마트 컨트랙트의 치명적 약점 재진입 공격 이해하기

블록체인 생태계에서 스마트 컨트랙트는 신뢰할 수 있는 중개자 없이 계약을 자동으로 실행하는 혁신적인 도구입니다. 하지만 이 코드가 완벽하지 않을 때 발생하는 보안 사고는 막대한 자산 손실로 이어집니다. 그중에서도 재진입(Reentrancy) 공격은 이더리움 역사상 가장 유명한 해킹 사건인 ‘DAO 해킹’의 주범으로, 스마트 컨트랙트 개발자라면 반드시 이해해야 할 핵심 취약점입니다.

재진입 공격이 발생하는 근본 원리

재진입 공격은 외부 계약과의 상호작용 과정에서 발생합니다. 스마트 컨트랙트가 외부 주소로 자금을 전송할 때, 해당 주소가 악의적인 컨트랙트라면 전송받는 즉시 다시 원래의 컨트랙트 함수를 호출할 수 있습니다. 이때 원래의 컨트랙트가 상태를 업데이트하기 전이라면, 공격자는 마치 잔액이 아직 차감되지 않은 것처럼 속여 자금을 반복적으로 인출하게 됩니다.

이 과정을 쉽게 비유하자면 은행에서 현금을 인출할 때, 창구 직원이 돈을 건네주기 전에 시스템에 ‘출금 완료’라고 기록하지 않는 것과 같습니다. 공격자는 돈을 받는 순간 창구 직원이 기록을 남기기 전임을 틈타, 다시 출금을 요청하여 또 다른 돈을 받아내는 방식입니다.

공격이 성립하는 핵심 구조

  • 상태 변경 전 외부 호출: 잔액을 업데이트하거나 기록을 수정하기 전에 외부 컨트랙트로 이더를 보냅니다.
  • 폴백 함수 활용: 외부 컨트랙트는 자금을 받는 즉시 실행되는 fallback 또는 receive 함수를 통해 원래 컨트랙트의 함수를 다시 호출합니다.
  • 반복 실행: 원래 컨트랙트는 이전 실행이 완료되지 않았으므로 잔액이 그대로 남아있는 것으로 인식하고 다시 인출을 승인합니다.

재진입 공격의 주요 유형과 특성

재진입 공격은 단순히 잔액을 빼내는 것 외에도 다양한 형태로 변주됩니다. 개발자들이 인지해야 할 대표적인 유형은 다음과 같습니다.

단일 함수 재진입

가장 고전적인 형태입니다. 동일한 함수 내에서 외부 호출이 발생하고, 그 외부 호출이 다시 동일한 함수를 호출하는 방식입니다. 주로 인출 함수에서 자주 발생합니다.

교차 함수 재진입

동일한 변수를 공유하는 두 개의 다른 함수를 이용합니다. 예를 들어, A 함수에서 인출을 처리하는 동안 B 함수에서 해당 변수를 참조하게 하여, 두 함수가 서로 간섭하며 상태를 왜곡시키는 방식입니다. 이 유형은 코드가 복잡할 경우 발견하기가 매우 어렵습니다.

읽기 전용 재진입

직접적인 자금 탈취가 아닌, 특정 시점의 잔액을 참조하여 가격을 산출하는 프로토콜에서 주로 발생합니다. 잘못된 잔액 상태를 외부로 노출하여 오라클 가격을 조작하거나, 다른 프로토콜의 판단을 흐리게 만드는 공격입니다.

재진입 공격을 방어하는 실용적인 방법

스마트 컨트랙트 개발 시 이러한 공격을 미연에 방지하기 위해 반드시 적용해야 하는 보안 패턴들이 있습니다. 비용 효율적이면서도 강력한 방어 기법들을 소개합니다.

체크 이펙트 인터랙션 패턴

가장 중요하고 기본적인 방어 기법입니다. 코드를 작성할 때 다음 순서를 엄격히 지켜야 합니다.

    • Check: 조건이 충족되는지 확인합니다. (예: 잔액이 충분한가?)
    • Effect: 내부 상태를 즉시 업데이트합니다. (예: 잔액을 0으로 변경)
    • Interaction: 외부 호출을 수행합니다. (예: 자금 전송)

이 순서만 지켜도 외부 호출이 다시 들어왔을 때, 이미 잔액이 업데이트되어 있어 공격은 실패하게 됩니다.

재진입 방지 락 적용

오픈제플린(OpenZeppelin)과 같은 신뢰할 수 있는 라이브러리에서 제공하는 ‘ReentrancyGuard’를 사용하는 것이 좋습니다. 이는 수정자(Modifier)를 사용하여 함수 실행 중에 동일한 함수나 다른 보호된 함수로의 재진입을 원천 차단하는 방식입니다.

최소한의 가스 전달

외부로 이더를 보낼 때 call 대신 transfer를 사용하면 가스 제한이 2300으로 고정됩니다. 이 정도의 가스는 fallback 함수에서 복잡한 로직을 수행하기에 부족하므로 공격을 물리적으로 차단할 수 있습니다. 다만, 최근에는 가스비 변동으로 인해 call을 권장하는 추세이므로, 이 방법보다는 체크 이펙트 인터랙션 패턴을 사용하는 것이 더 권장됩니다.

전문가가 말하는 보안의 중요성

많은 개발자가 “내 컨트랙트는 간단해서 괜찮겠지”라는 오해를 합니다. 그러나 스마트 컨트랙트는 한 번 배포되면 수정이 어렵고, 모든 상호작용이 투명하게 공개되므로 공격 대상이 되기 매우 쉽습니다. 보안 전문가들은 다음과 같은 조언을 건넵니다.

    • 코드 복잡도를 낮추세요: 기능이 많아질수록 공격 포인트는 늘어납니다. 핵심 기능에 집중하고 외부 의존성을 최소화하세요.
    • 외부 호출을 신뢰하지 마세요: 외부 컨트랙트가 어떤 로직을 가졌는지 알 수 없으므로, 항상 악의적인 상태라고 가정하고 방어적으로 설계해야 합니다.
    • 감사(Audit)는 필수입니다: 전문가의 코드 리뷰는 단순히 버그를 찾는 것이 아니라, 전체적인 아키텍처의 취약점을 파악하는 가장 효율적인 투자입니다.

자주 묻는 질문과 답변

Q: 재진입 공격은 오직 이더리움에서만 발생하나요?

A: 아닙니다. 스마트 컨트랙트를 지원하는 모든 EVM 기반 체인(BSC, Polygon, Arbitrum 등)에서 동일하게 발생할 수 있습니다. 솔리디티 언어의 특성에서 기인한 것이므로 모든 EVM 환경에서 주의가 필요합니다.

Q: 테스트넷에서 테스트하면 안전한가요?

A: 테스트는 필수이지만, 테스트넷에서의 성공이 메인넷의 안전을 보장하지 않습니다. 정적 분석 도구(Slither, Mythril 등)를 사용하여 코드를 스캔하고, 유닛 테스트 시 다양한 악의적 시나리오를 가정한 테스트 케이스를 작성해야 합니다.

Q: 이미 배포된 컨트랙트는 어떻게 하나요?

A: 배포 후 취약점이 발견되었다면 즉시 프록시 패턴을 활용한 업그레이드나, 긴급 중단(Emergency Stop) 기능을 사용하여 자산을 보호해야 합니다. 만약 코드가 불변(Immutable)이라면 자산을 안전한 주소로 이동시키는 마이그레이션이 유일한 방법입니다.

개발자를 위한 체크리스트

  • 외부로 이더를 보내기 전에 모든 내부 상태를 변경했는가?
  • ReentrancyGuard 수정자를 적절한 함수에 적용했는가?
  • 외부 호출을 하는 함수가 다른 함수와 공유하는 상태 변수를 수정하지 않는가?
  • 오라클 가격 참조 시 재진입 가능성을 배제했는가?
  • 보안 감사 도구를 통해 정기적으로 코드를 점검하고 있는가?

스마트 컨트랙트 보안은 단 한 번의 실수로 모든 것을 잃을 수 있는 냉혹한 영역입니다. 재진입 공격은 그중에서도 가장 빈번하고 파괴적인 위협입니다. 위에서 설명한 방어 기법들을 개발 프로세스에 내재화하고, 항상 보수적인 관점에서 코드를 검토하는 습관을 들인다면, 더 안전하고 신뢰받는 탈중앙화 서비스를 구축할 수 있을 것입니다.

heanajiser

heanajiser
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!
광고보고 콘텐츠 계속 읽기
원치않으시면 뒤로가기를 해주세요

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.

광고보고 콘텐츠 계속 읽기
원치않으시면 뒤로가기를 해주세요