2016년, 더 다오(The DAO) 해킹 사건이 터져 약 360만 이더리움(ETH)이 사라졌을 때, 나는 이 분야를 오랫동안 지켜봐 온 우리 모두가 숨을 헙 들이켰던 순간을 기억한다. 단순히 해킹 사건이 아니었다. 코드가 결함투성이일 때 "코드는 곧 법"이라는 잔혹한 현실을 일깨워준 심오하고도 초기적인 교훈이었다.
그때 나를 강하게 사로잡았던 것, 그리고 오늘날까지도 깊이 공감하는 바는, 기술이 눈부신 속도로 발전했음에도 스마트 계약 보안의 근본적인 문제들이 결국 인간의 실수와 시스템적인 허점으로 귀결된다는 점이다. 수십 년간 쌓아온 나의 관점은 이것이 한 번에 "해결"되는 문제가 아니라는 것이다.
이는 끊임없이 진화하는 싸움이며, 오래된 취약점이 패치되는 속도만큼이나 빠르게 새로운 공격 벡터가 출현한다. 문제는 단순히 코드에만 있지 않다. 설계와 감사부터 배포, 그리고 지속적인 감시에 이르는 전체 라이프사이클에 걸쳐 존재한다.
배경
더 다오 사건은 겉보기에 미묘한 코딩 결함이 어떻게 치명적인 손실로 이어질 수 있는지를 생생하게 보여주는 뼈아픈 교훈으로 남아 있다. 공격자는 재진입(reentrancy) 취약점을 악용했는데, 이는 외부 계약에 대한 호출이 원래 계약의 상태가 업데이트되기 전에 "재진입"할 수 있는 메커니즘이다.
ATM에서 돈을 인출하는데, 잔고가 차감되기도 전에 또 다른 인출을 시작할 수 있다고 상상해 보라. 본질적으로 이런 일이 일어난 것이다. 공격자는 withdrawRewardFor 함수를 반복적으로 호출하여 자금을 빼돌렸다. 외부 호출이 이루어지기 전에 잔고가 업데이트되지 않아, 동일한 초기 잔고에서 여러 번 인출할 수 있었기 때문이다.
이것은 이더리움 프로토콜 자체의 결함이 아니라, 더 다오의 스마트 계약 설계 오류였다. 이 사건은 이더리움 블록체인의 하드 포크를 강제했고, 이로 인해 이더리움 클래식이 탄생했다. 이는 스마트 계약 취약점의 엄청나고 즉각적인 결과를 극명하게 보여준 전례 없는 사건이었다.
이것은 단발성 사건이 아니었고, 이후에도 다양한 논리적 결함이 혼란을 일으키는 것을 마지막으로 본 것도 아니었다. 이 사건은 블록체인의 핵심 원칙인 불변성이 곧 불변하는 버그를 의미하기도 한다는 점을 가르쳐 주었다. 일단 배포되면 취약한 계약은 시한폭탄과 같으며, 종종 악용된 후에야 발견되곤 한다.
기술적 분석
스마트 계약 취약점의 지형은 재진입을 훨씬 넘어선다. 개발자가 이러한 자체 실행 계약을 작성하고 상호 작용하는 방식의 다양한 측면에 걸쳐 있다. 수년 동안 나는 수많은 패턴들이 나타나는 것을 목격했고, 각 패턴은 저마다의 파괴적인 양상을 띠었다.
2017년 패리티(Parity) 월렛 다중서명(multi-sig) 사건을 생각해 보자. 서로 다른 취약점의 단면을 보여주는 두 가지 개별적인 사건이 있었다. 2017년 7월에 발생한 첫 번째 사건은 패리티 다중서명 월렛 라이브러리 계약의 initWallet 함수에 존재하는 취약점과 관련이 있었다.
공격자는 이미 배포된 월렛에서 이 초기화 함수를 호출하여 효과적으로 소유자가 되었고, 자금을 빼돌렸다. 정확한 금액은 공개되지 않았지만 상당한 액수였다. 이 사건의 근본 원인은 접근 제어 결함이었다. 초기 설정에 사용되어야 할 initWallet 함수가 여러 번 호출될 수 있었고, 이는 정당한 소유권을 무력화시켰다.
같은 해 2017년 11월, 또 다른 패리티 다중서명 월렛 사건이 발생했는데, 이번에는 훨씬 더 광범위한 결과를 초래했다. 한 사용자가 월렛을 시험하던 중 실수로 많은 패리티 다중서명 월렛이 의존하고 있던 라이브러리 계약에 대한 자폭(self-destruct) 기능을 실행했다. 이 월렛들은 공유 라이브러리에 대한 호출을 위임하도록 설계되었기 때문에, 해당 라이브러리의 파괴는 의존하는 모든 월렛을 사용할 수 없게 만들었고, 수억 달러 상당의 이더리움이 동결되었다.
출처에는 정확한 금액이 명시되어 있지 않지만 상당한 규모였다. 이것은 전통적인 의미의 해킹이 아니라, 치명적인 논리 오류이자 설계 결함이었다. 즉, 적절한 안전장치 없이 공유되고 중요한 구성 요소를 자폭시킬 수 있는 능력은 자금 접근의 돌이킬 수 없는 손실로 이어졌다. 이는 계약 간 상호 의존성의 위험성과 파괴적인 경로를 포함한 모든 가능한 실행 경로에 대한 강력한 테스트의 필요성을 강조했다.
이러한 사례들은 몇 가지 일반적인 기술적 취약점 범주를 조명한다.
접근 제어 결함: 패리티 사건에서 보았듯이, 누가 어떤 함수를 호출할 수 있는지에 대한 부적절한 관리.
정수 오버플로우/언더플로우: 최신 솔리디티(Solidity)에서는 SafeMath 라이브러리로 인해 덜 일반적이지만, 오래된 계약들은 산술 연산이 최대/최소 정수 값을 초과하거나 미달하여 부정확한 계산과 잠재적인 자금 조작으로 이어질 수 있었다.
논리 오류: 패리티 자폭 사건이 대표적인 예이다. 코드는 지시받은 대로 정확히 작동하지만, 그 지시가 예상치 못한 치명적인 결과를 초래하는 경우이다.
선행매매(Front-running): 공격자는 밈풀(mempool)에서 보류 중인 거래를 관찰하고 더 높은 가스 가격으로 자신의 거래를 제출하여 원래 거래보다 먼저 실행한다. 이는 종종 덱스(DEX) 거래나 NFT 발행과 같은 예측 가능한 계약 행동을 악용한다.
서비스 거부(DoS) 공격: 항상 직접적인 자금 손실로 이어지지는 않지만, DoS 공격은 접근을 차단하거나 가스 한도를 소진시켜 계약을 사용할 수 없게 만들 수 있다.
실제 사례
생태계가 성숙해짐에 따라 공격의 정교함도 진화했다. 우리는 단순히 잘못 작성된 솔리디티 코드 라인에 관한 것이 아니라, 더 광범위한 운영 보안, 인적 요소, 그리고 상호 연결된 시스템의 아키텍처에 관한 취약점들을 목격하기 시작했다. 2022년 3월 로닌 브릿지(Ronin Bridge) 해킹 사건은 이러한 진화의 명백한 증거이며, 약 6억 2,500만 달러 상당의 이더리움과 USDC가 도난당했다.
로닌 사이드체인을 이더리움 메인넷에 연결하는 로닌 브릿지는 트랜잭션을 승인하기 위해 일련의 검증자들에게 의존했다. 인출의 경우, 9명의 검증자 중 최소 5명의 서명이 필요했다. 공격자들은 5개의 프라이빗 키를 확보했는데, 4개는 스카이마비스(Sky Mavis, 액시 인피니티와 로닌의 개발사)로부터, 1개는 액시 다오(Axie DAO) 검증자로부터 얻었다.
이것은 전통적인 의미의 스마트 계약 코드 익스플로잇이 아니었다. 프라이빗 키의 침해였으며, 스카이마비스 직원들을 대상으로 한 사회 공학(social engineering) 또는 표적 피싱 공격을 통해 이루어졌을 가능성이 높다. 출처에는 프라이빗 키 도난 외에 정확한 침해 메커니즘은 공개되지 않았다.
이 사건은 몇 가지 중요한 시스템적 및 운영적 취약점을 강조한다.
중앙화 리스크: 탈중앙화의 약속에도 불구하고, 많은 브릿지 설계는 여전히 비교적 적은 수의 신뢰할 수 있는 검증자들에게 의존한다. 이러한 키 보유자들의 대다수를 침해하면 공격자는 모든 암호화 보안을 우회할 수 있다.
프라이빗 키 관리: 블록체인 네트워크의 보안은 궁극적으로 프라이빗 키의 보안에 달려 있다. 만약 이것들이 도난당하면, 아무리 스마트 계약을 강화해도 침해를 막을 수 없다. 이는 종종 인간의 경계심, 강력한 내부 보안 프로토콜, 그리고 다단계 인증에 달려 있다.
공급망 공격: 하나의 주체(스카이마비스)의 침해는 전체 브릿지에 연쇄적인 영향을 미쳤고, 다자 시스템에서 가장 약한 고리가 전체를 위험에 빠뜨릴 수 있음을 보여주었다.
탐지 시간: 로닌 브릿지 공격은 거의 일주일 동안 감지되지 않았으며, 사용자가 자금을 인출할 수 없다고 보고한 후에야 발견되었다. 이 지연으로 인해 공격자들은 훔친 자산을 옮길 충분한 시간을 확보했다.
이러한 사례들은 코드 감사와 정형 검증이 필수 불가결하지만, 만능 해결책은 아니라는 것을 보여준다. 코드를 작성하는 개발자부터 인프라와 프라이빗 키를 관리하는 운영자에 이르기까지 인간적 요소는 완벽하게 보안하기 매우 어려운 복잡성을 더한다.
한계
업계는 이러한 고통스러운 경험으로부터 분명히 배웠다. 오늘날 우리는 다음과 같은 더욱 강력한 보안 관행을 갖추고 있다.
포괄적인 감사: 독립적인 보안 회사들이 스마트 계약 코드를 면밀히 검토하여 취약점을 찾는다. 그러나 감사는 특정 시점의 스냅샷일 뿐이며, 감사자와 검토 범위만큼만 유효하다. 미묘한 버그나 새로운 공격 벡터를 놓칠 수 있다.
정형 검증: 이 수학적 접근 방식은 사양에 대해 스마트 계약 코드의 정확성을 증명하려고 시도한다. 강력하지만, 자원 집약적이고 종종 복잡하며, 여전히 사양 자체의 정확성에 의존한다. 훌륭한 도구이지만, 경제적 인센티브나 오프체인 운영 결함에서 비롯되는 모든 유형의 취약점에 대한 만능 해결책은 아니다.
버그 바운티 프로그램: 악의적인 행위자들보다 먼저 화이트햇 해커들이 취약점을 찾아보고하도록 장려하는 것이 표준 관행이 되었다.
탈중앙화 보안 조치: 브릿지와 오라클과 같은 중요한 인프라를 탈중앙화하여 단일 실패 지점을 줄이는 데 진전이 이루어지고 있다.
그러나 한계는 여전히 존재한다. 디파이(DeFi)의 빠른 혁신 속도는 새로운 기본 요소와 복잡한 상호 작용이 끊임없이 배포됨을 의미하며, 종종 오랜 기간 동안 실전 검증을 거치기도 전에 배포된다. 디파이의 구성 가능성은 강력하지만, 한 프로토콜의 취약점이 그것과 통합된 다른 많은 프로토콜에 연쇄적으로 영향을 미칠 수도 있음을 의미한다.
더욱이, 이 공간의 경제적 인센티브는 엄청나므로, 정교한 공격자들에게는 수익성 높은 표적이 된다. 블록체인의 익명성은 또한 도난당한 자금을 추적하고 회수하는 것을 극도로 어렵게 만든다. 우리는 과연 이토록 막대한 가치를 보호할 만큼 충분히 탄력적인 시스템을 구축하고 있는가? 나는 종종 이런 의문을 품는다.
결론
스마트 계약 보안의 진화는 끝나지 않았다. 이는 새로운 도전과 해결책이 끊임없이 나타나는 역동적인 분야이다. 앞으로 몇 년 동안 보안의 흐름을 좌우할 몇 가지 핵심 영역이 있다고 생각한다.
첫째, 이더리움의 계정 추상화(AA), 특히 ERC-4337 표준의 진행 상황과 채택에 주목해야 한다. AA는 명시적인 보안 기능은 아니지만, 스마트 계약 월렛을 일등 시민으로 만들어 다중서명 거래, 소셜 복구, ERC-20 토큰으로 가스비 지불과 같은 기능을 외부 소유 계정(EOA)이 아닌 스마트 계약으로 관리할 수 있게 하는 것을 목표로 한다.
2024년과 2025년 동안 ERC-4337의 광범위한 채택이 가속화되고, EOA에서 스마트 계약 월렛으로의 상당한 전환이 일어난다면, 더 프로그래밍 가능하고 잠재적으로 더 안전한 사용자 계정 기반이 일반적인 프라이빗 키 위험을 완화할 수 있다는 아이디어를 입증할 것이다. 반대로, 광범위한 채택이 정체되거나 AA 구현 내부에서 새롭고 예상치 못한 취약점이 발생한다면, 계정 관리의 근본적인 변화조차도 그 자체로 복잡한 보안 문제를 안고 있으며, AA가 새로운 공격 표면을 도입하지 않고 전반적인 보안을 크게 향상시킨다는 가정을 무효화할 수 있음을 시사할 것이다.
둘째, 타임락(time-locked) 실행을 포함한 완전한 온체인 거버넌스 시스템의 개발 및 배포를 주시하고 있다. 많은 다오(DAO)는 여전히 중요한 결정과 실행을 위해 다중서명이나 오프체인 구성 요소에 의존한다. 그러나 일부 프로젝트는 제안, 투표, 실행이 전적으로 스마트 계약으로 관리되며, 종종 성공적인 투표와 실행 사이에 의무적인 시간 지연(예: 24~48시간)이 있는 더욱 강력하고 완전한 온체인 거버넌스로 나아가고 있다.
2024년 내내 주요 프로토콜들이 이러한 타임락 온체인 거버넌스를 성공적으로 구현하고 유지하며, 시간 지연을 악용하는 주요 익스플로잇(예: 투표를 조작하는 플래시 론 공격이나 실행 선행매매)이 없다면, 강력하고 투명한 거버넌스 메커니즘이 탐지 및 개입할 수 있는 기회를 제공하여 보안을 강화할 수 있다는 아이디어를 강화할 것이다. 그러나 이러한 시스템이 타임락 기간을 악용하는 정교한 경제적 공격의 표적이 되거나, 중요한 버그에 대한 신속한 대응에는 너무 번거롭다는 것이 입증된다면, 완전히 탈중앙화되고 안전한 거버넌스의 이상은 여전히 실질적인 한계에 직면해 있으며, 이러한 메커니즘이 본질적으로 보안을 향상시킨다는 개념에 도전하게 될 것이다.
진정으로 안전한 스마트 계약을 향한 여정은 아직 멀고 험하다. 이 길은 끊임없는 학습과 적응, 그리고 건강한 회의론을 요구한다.
※ 본 칼럼은 정보 제공을 목적으로 하며, 투자 권유가 아닙니다. 모든 투자 결정은 본인의 판단과 책임 하에 이루어져야 합니다.