무허가 머클 트리 공격
솔라나 온체인 프로그램에서 무허가형 cNFT를 발행하는 것이 좋은 생각이 아닐 수 있는 이유
블라드(Vlad)는 액세스 프로토콜의 풀 스택 소프트웨어 엔지니어입니다. 엑스(트위터) 또는 이메일을 통해 블라드에게 연락하실 수 있습니다.
이전 글들(1, 2)과 리포지토리에서는 온체인 프로그램에서 탈중앙화 메커니즘을 생성하여 사용자의 지갑에 cNFT를 발행하는 방법을 설명했습니다. 해당 설명에서는 누구나 온체인 프로그램을 호출하여 자신의 지갑에 cNFT를 발행할 수 있었습니다. 이 글에서는 여기에 추가적인 확인 절차를 도입해야 하는 이유를 간략히 설명하고자 합니다.
이미 알고 계시겠지만, cNFT 데이터는 온체인에 직접 저장되는 것이 아니라 원장에 저장됩니다(온체인 거래 내역의 로그라고 생각하시면 됩니다). 체인에 직접 저장되는 유일한 것은 cNFT를 변조할 수 없도록 보장하는 머클 트리의 일부분으로, 잎이 cNFT 데이터의 해시와 동일합니다. 이는 매우 비용 효율적이며, cNFT를 저렴하게 만듭니다.
공격 벡터
앞서 언급한 리포지토리의 온체인 프로그램에서는 누구나 머클 트리 계정을 만들 수 있습니다. 여기서 우리는 온체인 프로그램 작성자가 온체인 프로그램이 작동을 멈추지 않도록 하기 위해, 기존 트리가 채워질 경우 새로운 트리를 생성할 것이라고 가정할 수 있습니다. 이는 충분한 자금을 가진 사람이라면 누구나 머클 트리를 가득 채우고 계속해서 새로운 트리를 생성하는 데 비용을 사용하도록 만들 수 있는 공격 벡터를 열어줍니다.
간단한 계산을 통해 공격자가 여러분에게 미칠 수 있는 영향력을 이해해 보겠습니다: 프로그램이 최대 깊이 14, 캐노피 깊이 11의 트리로 작동한다고 가정해 보겠습니다:
- 트리 생성 비용은 ~1.134 SOL입니다.
- 이 트리는 최대 16,384개의 cNFT를 저장할 수 있습니다.
- 새로운 cNFT를 발행하는 데는 5000 램포트(Lamport)가 필요합니다.
따라서 전체 트리를 채우는 데는 0.08192 SOL이 필요합니다.
보시다시피, 발행 권한을 누구에게나 개방하면 공격자는 생성 비용의 1/10도 안 되는 비용으로 머클 트리를 쉽게 채울 수 있으므로 프로그램을 계속 작동시키기 위해 많은 자금을 소비하게 됩니다. 이 시나리오에서는 공격자가 직접적으로 자금을 훔치지는 않더라도 프로그램을 사용할 수 없게 만들고 사용자를 협박할 수 있습니다.
간단한 솔루션
안타깝게도 여기에는 완벽한 해결책이 없으며, 여러분은 여러분의 프로그램의 목적이 무엇인지 결정해야 합니다. 그런 다음 공격자가 사용자보다 더 많은 비용을 지출하도록 조정하여 공격이 경제적으로 불가능하도록 만들어야 합니다.
몇 가지 간단하고 일반적인 해결책이 있습니다:
- 트리 생성 비용을 충당하기 위해 발행 과정에 조정 가능한 수수료를 추가합니다. 이 수수료는 트리 생성 비용을 지불하는 계정으로 이체할 수 있습니다.
- 수수료를 특정 지갑으로 보내는 대신 소각합니다. 이는 좀 더 탈중앙화된 접근 방식입니다.
- 지갑당 하나의 발행만 허용하려면 지갑 주소에서 파생된 PDA를 초기화하면 됩니다. 이렇게 하면 발행 비용이 0.001 SOL 이상으로 높아지므로 수수료도 해결됩니다.
- cNFT가 다른 더 비싼 온체인 작업에 대한 보상으로 제공되는 경우, 이 작업이 수행되었다는 확인을 발행 인스트럭션에 추가합니다. 조건이 충족된 경우에만 발행을 허용하면 됩니다.
cNFT를 지갑으로 사용할 때의 솔루션
솔라나의 모든 PDA는 지갑으로 사용할 수 있습니다. 따라서 cNFT 자산 ID에서 파생된 PDA를 다른 프로그램에 CPI로 사용할 수 있습니다. 이에 대한 한 가지 구체적인 사용 사례는 액세스 프로토콜 V2에서 찾을 수 있는데, 자금을 지갑에 직접 보관하는 대신 양도 가능한 cNFT에 잠글 수 있는 기능이 추가될 수 있습니다.
만약 여러분이 비슷한 목표를 가지고 있다면, 발행 과정을 세 부분으로 나누어 이를 달성할 수 있습니다:
이렇게 하면 cNFT 발행 가격을 5000 램포트(Lamport)로 유지하고, 공격자가 다른 곳에 지불하도록 할 수 있습니다. 예를 들어, 액세스 프로토콜 V2의 경우 $ACS 토큰을 풀에 고정하여 이를 해결합니다.
결론
온체인 프로그램에서 머클 트리를 순전히 무허가성으로 유지하는 것은 위험합니다. 여러분보다 10배나 적은 자금을 가진 한 개인이 여러분의 프로그램을 다시는 사용할 수 없게 만들 수 있기 때문입니다.
그러나 이러한 방법들을 통해 사용자에게 피해를 주지 않고도 아주 쉽게 완화할 수 있습니다.