autorenew
Solana PDA 사칭: 누락된 검사 하나가 런치패드 토큰 탈취로 이어진 방법

Solana PDA 사칭: 누락된 검사 하나가 런치패드 토큰 탈취로 이어진 방법

빠르게 움직이는 Solana 개발 환경에서는 고속 트랜잭션과 혁신적인 DeFi 도구가 만나는 곳에서, 코드의 작은 실수 하나가 대형 익스플로잇의 문을 열어줄 수 있습니다. 바로 그런 일이 3월 MetaDAO의 런치패드 감사에서 일어났습니다—Program Derived Addresses (PDAs)와 관련된 미묘한 버그로, 공격자가 막 발행된 토큰을 빨아들일 수 있었습니다. Solana 보안업체 Accretion의 "Advent of Bugs" 시리즈 일환인 이 Day 1 공개는 PDA 사칭 취약점을 드러내며, 모든 블록체인 개발자에게 서명자 검증을 다시 확인하라는 강력한 경고입니다.

Solana 스마트 컨트랙트에 깊게 관여하고 있든, 막 발행되는 밈 토큰 런치에 발을 담그고 있든, 계속 읽어보세요. 무엇이 잘못됐는지 분해하고, 공격 과정을 단계별로 설명하며, 프로젝트를 안전하게 지키기 위한 핵심 교훈을 공유하겠습니다. 박사학위는 필요 없습니다—그저 명확하고 직관적인 인사이트로 방어력을 높이세요.

설정: PDA에 대한 런치패드의 신뢰

MetaDAO의 런치패드는 Solana 전반에 걸쳐 폭발적으로 등장하는 바이럴 밈 코인 출시처럼 토큰 출시를 원활하고 탈중앙화되게 만들도록 설계되었습니다. 새로운 런치를 초기화할 때 프로그램은 launch_signer라는 특별한 계정을 생성합니다. 이 계정은 단순한 계정이 아니라 해당 런치의 키와 고정된 시드("launch_signer")로부터 파생된 PDA입니다. PDAs는 개인키 없이도 프로그램 로직으로만 제어되는 "signer" 계정을 결정론적으로 생성하는 Solana 방식입니다.

아이디어는 간단합니다: launch_signer PDA는 새 토큰의 mint authority로 작동합니다. 지정된 계정에 초기 토큰을 발행하는 데 서명하여 런치를 시작하게 되는 것이죠. 이를 안전하게 수행하기 위해 프로그램은 제공된 시드를 사용해 PDA를 대신해 "서명"할 수 있는 invoke_signed를 사용합니다.

하지만 문제가 발생한 지점이 여기였습니다. 해당 인스트럭션은 제공된 launch_signer 계정이 실제로 기대한 PDA 주소와 일치하는지를 명시적으로 검증하지 않았습니다. 대신 invoke_signed에 시드를 넘겨주면 모든 것이 처리될 것이라 믿었습니다. 스포일러: 그렇지 않았습니다.

드러난 버그: 서명자 사칭

Accretion의 감사팀은 문제를 발견했습니다: 프로그램은 launch_signer를 UncheckedAccount로 표시했고, 이는 주소에 대한 내장된 검증이 없음을 의미합니다. 이로 인해 임의의 Solana 계정을 전달할 수 있었는데—조건은 트랜잭션에서 최상위 서명자(top-level signer)여야 하고 mint의 authority와 일치해야 한다는 것뿐이었습니다.

왜 이게 중요한가요? Solana에서는 invoke_signed에 잘못된 시드를 넣어도, 계정이 이미 외부 트랜잭션을 서명하고 있으면 함수가 실패하지 않습니다. 시드는 무시되고 공격자의 키페어로부터 나온 실제 서명이 대신 작동합니다. 바로—사칭이 성사됩니다.

이것은 이론적인 극단적 위험이 아닙니다. 토큰 mint로 가는 백도어입니다.

실행된 공격: 런치 전에 토큰 훔치기

인기 있는 새 밈 토큰 출시를 노리는 공격자의 입장이 되어보면, 다음과 같이 악용할 수 있습니다:

  1. 준비물 만들기: 새 mint 계정을 만들고, 자신의 키페어(이를 K라고 부르겠습니다)를 mint authority로 설정합니다. 그런 다음 K가 소유한 토큰 계정을 만들어 전리품을 받을 준비를 합니다.

  2. Init 트리거: InitializeLaunch 인스트럭션을 호출하면서 launch_signer로 K를 전달합니다. K가 최상위 트랜잭션에 서명하도록 합니다—자신이 제어하는 키이니 쉽습니다.

  3. 백도어 공급 발행: 프로그램은 PDA 시드를 통해 서명한다고 생각하며 K 소유 계정으로 기쁘게 토큰을 mint합니다. 그러나 실제로는 당신의 키페어 서명이 일을 처리하고, 시드는 무시됩니다.

  4. 흔적 지우기: 경보를 피하기 위해 훔친 토큰의 대부분을 다시 전송하고, mint authority를 실제 PDA에 넘겨 런치가 예정대로 진행되게 합니다. 당신은 불법 할당을 확보했고, 프로젝트 측은 모든 것이 정상이라고 생각합니다.

수시간 내에 수백만 달러가 펌핑될 수 있는 밈 토큰 세계에서는, 커뮤니티가 알아채기 전에 고래급 지분을 챙기는 것이 가능할 수 있습니다. "to the moon"이 "to the attacker's wallet"로 변하는 은밀한 익스플로잇 유형입니다.

(누락된 검증을 강조한 코드 스니펫의 주석 처리된 Rust 코드를 시각적으로 보려면 아래 스레드의 주석된 코드를 확인하세요.)

launch_signer의 PDA 유도와 검증 누락을 보여주는 주석 처리된 Solana Rust 코드

왜 이런 일이 발생하는가: Solana 서명 특성에 대한 간단한 설명

PDA가 처음이라면, 이를 프로그램이 제어하는 "무형의 서명자(ghost signer)"로 생각하세요. 이들은 find_program_address를 사용해 ["launch_signer", launch.key()]와 같은 시드로부터 파생되어, CPI(Cross-Program Invocations)에서 시드를 통해서만 프로그램이 "서명"할 수 있게 보장합니다.

하지만 Solana의 유연성은 양날의 검입니다. invoke_signed는 PDA 주소를 ed25519 곡선에서 오프셋하도록 시드에 의존해 프로그램적 서명을 가능하게 합니다. 명시적인 주소 검사(e.g., require_keys_eq!(launch_signer.key(), expected_pda))가 없다면, 공격자가 자신의 서명자로 바꿔 넣을 수 있습니다. 스레드의 두 번째 이미지는 unchecked mint를 포함한 전체 인스트럭션 흐름을 보여줍니다.

unchecked launch_signer PDA로 토큰 mint를 수행하는 Solana 인스트럭션 코드

이것은 고전적인 "신뢰하되 검증하라(trust, but verify)"의 사례—코드 관점에서는 항상 검증하라는 얘기입니다.

Solana 개발자와 밈 토큰 빌더를 위한 교훈

Accretion의 수정 방법은 간단합니다: 전달된 launch_signer가 파생된 PDA와 일치하는지 확인하는 검사를 추가하세요. 더 이상 사칭은 없습니다.

특히 밈 토큰과 런치패드의 황야에서 Solana 위에 구축하는 모든 사람을 위한 더 넓은 시사점:

  • 항상 PDAs를 검증하라: invoke_signed를 사용할 때, 기대되는 PDA를 계산하고 제공된 계정과 같다고 단언하세요. 비용은 적고 효과는 확실합니다.

  • 가능하면 UncheckedAccount를 피하라: UncheckedAccount는 유연성에 유용하지만, 서명자에 대한 명시적 검사와 함께 사용하세요.

  • 일찍, 자주 감사를 받아라: 이 버그는 초기 리뷰를 통과했습니다. Accretion 같은 업체가 이런 문제를 찾아내고 있으니—다음 런치 전에 고려해보세요.

  • 엣지 케이스를 테스트하라: solana-program-test 같은 도구로 서명자 불일치 공격을 시뮬레이션해 발견하세요.

밈 토큰 생태계에서는 과대광고가 코드 리뷰보다 가치를 빠르게 밀어올리기 때문에, 이런 취약점이 프로젝트를 만들거나 깨뜨릴 수 있습니다. MetaDAO는 감사 후 이 문제를 패치했지만, 이런 이야기는 커뮤니티를 긴장하게 만듭니다.

마무리: 보안은 쌓이고, 버그는 그럴 필요가 없다

"Advent of Bugs" 시리즈는 훌륭한 시작을 알리며, Solana의 속도가 느슨한 보안을 정당화하지 못한다는 점을 상기시킵니다. 이 사례를 공유한 @r0bre와 Accretion 팀에게 박수를 보냅니다—안전하고 확장 가능한 런치를 추구하는 개발자에게는 금과 같습니다.

Solana 프로젝트를 준비 중이신가요? 댓글로 경험을 남겨주세요: PDA 문제를 겪어본 적이 있나요? 당신의 해결법은 무엇인가요? 그리고 Meme Insider에서 밈 토큰 감사를 진행하고 있다면, 안전한 런치에 대한 최신 정보를 얻으려면 저희에게 연락하세요.

항상 경계하세요—블록체인에서는 하나의 검증되지 않은 서명자가 천 개의 익스플로잇을 촉발할 수 있습니다.

추천 기사