트랜잭션 서명 단계의 취약점: 소프트웨어 지갑의 구조적 한계와 하드웨어 지갑의 대응력 동향
트랜잭션 서명 단계의 취약점: 소프트웨어 지갑의 구조적 한계와 하드웨어 지갑의 대응력 동향

서론 : npm 공급망 공격과 서명 레이어의 취약점
2025년 9월, 자바스크립트 생태계를 강타한 npm 공급망 공격은 프론트엔드 개발자의 의존성 관리에 뼈아픈 교훈을 남겼다.
공격자는 유명한 패키지 메인테이너(qix)의 계정을 사회공학적으로 탈취한 뒤, debug, chalk, ansi-styles등 18개의 핵심 라이브러리에 악성 스크립트를 주입했다. 이 패키지들은 주간 다운로드 26억회가 넘는 거대한 생태계를 구성하고 있어, 단 2시간 동안 악성 버전이 올라온 것만으로도 수많은 빌드 환경에서 감염이 일어났다.
악성 스크립트는 브라우저 측에서 fetch, XMLHttpRequest, window.ethereum.request 같은 핵심 API를 후킹하고 네트워크 리스폰스와 트랜잭션 페이로드를 파싱해 지갑 주소와 토큰 승인 정보를 실시간으로 탐지했다. 탐지된 주소는 look‑alike pattern으로 위장한 공격자 주소를 바꿔치기(rewrite) 되었고, 사용자가 “Confirm” 버튼을 누르기 직전에 메모리 상의 서명 데이터만 조작하는 방식이라 UI에는 정상적으로 보였다.
이 사건은 소프트웨어 지갑의 구조적 약점을 노린 정밀 공격이며, 개발자와 보안 연구자가 서명 레이어 보안 모델을 재고해야 함을 시사한다.
공격 메커니즘 분석
1. 공급망 침투 경로
- 계정 탈취 → 패키지 주입: 공격자는 npm 메인테이너 계정에 침투 후, 신뢰 받는 패키지들의 버전 업데이트를 가장해 악성 코드가 삽입된 tarball을 푸시했다. 패키지 메타데이터와 package.json을 조작해 무결성 검사를 우회했고, 종속 패키지를 통해 체인식 감염이 가능하도록 설계했다.
- CI/CD 오염: 많은 프로젝트에서 ^ 버전 범위를 사용해 자동 업데이트를 허용하고 있었기 때문에, CI 서버나 로컬 환경에서 npm install만 해도 악성 패키지가 내려받아졌다. Wiz의 텔레메트리 데이터에 따르면 노출 2시간 동안 조사된 클라우드 환경의 약 10%에서 악성 페이로드가 발견되었다.
2. 브라우저 후킹 및 트랜잭션 조작
- API Hooking: 악성 스크립트는 아래와 같이 표면적으로 동일한 함수 시그니처를 유지하면서 내부에서 로직을 가로채는 방식으로 구현되었다.
const originalFetch = window.fetch;
window.fetch = async (...args) => {
const response = await originalFetch(...args);
const cloned = response.clone();
const text = await cloned.text();
if (containsAddress(text)) {
// 주소 rewrite 로직
}
return response;
};
- 주소 탐지 및 교체: 악성 코드가 감지한 주소는 체인별 정규식으로 필터링된다. ETH 주소는 0x[a-fA-F0–9]{40}, BTC는 Base58 체크섬, SOL·TRX 등은 각 체인 표준을 사용한다. 찾은 주소를 공격자 주소로 교체하면서, UI에서 눈치채지 못하게 하기 위해 일부 앞/뒤 문자열을 동일하게 맞춰 look‑alike 주소를 만든다.
- Approval/Allowance 조작: 단순 송금뿐 아니라 ERC‑20 approve 호출의 spender 주소를 바꾸거나, NFT 전송 함수의 인자를 변경하는 등의 공격도 가능하다. 이로 인해 사용자는 인지하지 못한 채 공격자 컨트랙트에 토큰 사용 권한을 부여할 수 있다.
3. 스텔스 유지
- 자기삭제/self‑cleanup: 일부 패키지에서는 브라우저 콘솔 로그를 비활성화하거나, Object.defineProperty를 통해 후킹된 함수의 toString() 결과를 원본과 동일하게 반환하도록 수정해 탐지를 어렵게 했다.
- 환경 감지: 공격 스크립트는 개발 환경(Domain이 localhost 또는 127.0.0.1인 경우)을 감지해 동작을 최소화하거나 비활성화하였다. 이는 자동화 테스트나 보안 분석을 회피하기 위해 사용된다.
소프트웨어 지갑: 현황과 구조적 위험
시장 현황
- 사용자 비중: 2025년 글로벌 기준, 전체 암호화폐 지갑 사용자 중 약 78%가 소프트웨어 지갑(핫 월렛)을 사용하고, 하드웨어 지갑(콜드 월렛) 비율은 22% 정도에 그친다.
- 핫 월렛 매출 비중: 2024년 지갑 시장 매출 중 약 56%를 소프트웨어 지갑이 차지했으며, 하드웨어 지갑은 성장 중이지만 아직 작은 비중이다.
구조적 취약점
- 호스팅 환경 의존성: 소프트웨어 지갑은 브라우저 확장(예: MetaMask, Phantom)이나 모바일 앱으로 동작한다. 이는 앱 코드와 브라우저 API 사이에 서드파티 스크립트가 끼어들 여지를 제공한다. npm 공급망 공격처럼, 의존 패키지를 통해 악성 스크립트가 로딩되면 지갑 API를 후킹해 서명 데이터를 변조할 수 있다.
- 트랜잭션 요약 신뢰: 대부분의 소프트웨어 지갑은 UI에서 보여주는 “수신자 주소 · 금액 · 수수료” 등을 사용자가 보고 확인하도록 한다. 그러나 내부적으로 서명할 RLP/CBOR/JSON 데이터와 UI 표시값을 비교 검증하는 로직이 없다. 이로 인해 악성 코드가 tx.to 값을 바꿔도 UI에는 원래 값이 표시된다.
- 클립보드 하이재킹: 클립보드는 OS 차원에서 프로세스 간 공유된다. OSL 보고서에 따르면 클립보드 하이재킹 악성코드는 백그라운드에서 사용자가 복사한 지갑 주소를 감시하다가, 패턴을 감지하면 공격자 주소로 교체한다. 사용자는 소프트웨어 지갑 입력창에 붙여넣은 주소를 신뢰하기 때문에, 변조를 감지하지 못한다.
- 키 저장 취약: 소프트웨어 지갑은 브라우저의 localStorage, 모바일 앱의 암호화된 키체인 등에 개인 키를 저장한다. 하지만 기기 루팅, 브라우저 취약점, 악성 앱 등을 통해 키가 탈취될 가능성이 존재한다.
사례: 윈도우 클립보드 스틸러
Sonicwall 분석에서는 크립토 스틸러가 클립보드 데이터를 감시하고, 1만 개가 넘는 공격자 지갑 주소를 하드코딩해 교체하는 방식을 사용한 것으로 나타났다. 이 공격은 사용자가 붙여넣기를 실행하는 순간 자동으로 주소를 변조하므로, TX 서명 단계에서 변조를 인지하기 어렵다.
하드웨어 지갑: 보안 메커니즘과 시장 동향
보안 구조
- 오프라인 키 저장: 하드웨어 지갑(예: Ledger, Trezor)은 보안 엘리먼트 칩에 개인 키를 저장하고, 서명 연산을 칩 내부에서만 수행한다. 응용 프로그램은 서명 요청만 전달하고, 서명 결과만 받아 사용한다. 악성 스크립트가 브라우저를 후킹해도 서명 자체를 위조할 수 없다.
- 트랜잭션 정보 표시: 기기 화면에 to, value, data 해시 등을 표시하고, 사용자가 물리 버튼을 눌러 서명한다. 이는 UI 변조를 방지하며, 주소가 교체되었는지 직접 눈으로 확인할 수 있게 한다.
- 멀티체인 및 멀티시그 지원: 최신 장치들은 EVM, Solana, Bitcoin, TRON 등 여러 체인을 지원하며, 멀티시그(MPC/TSS) 기능도 제공한다. 이는 하나의 장치가 손상돼도 전체 키를 재구성할 수 없게 한다.
시장·채택 데이터
- 출하량 및 성장률: 2024년 글로벌 하드웨어 지갑 출하량은 580만 대 이상이며, 2025년에는 30% 이상 증가했다는 조사 결과가 있다.
- 시장 규모: SQ Magazine 보고서는 하드웨어 지갑 시장이 2025년 약 3.5억5.5억 달러 규모에서 2033년 25억255억 달러로 성장할 것으로 예상한다. 이는 연간 18.9~31%의 CAGR에 해당하며, 보안 수요와 규제 강화가 주요 동인이다.
- 사용자 통계: 2025년 기준, 전체 지갑 사용자 중 22%가 하드웨어 지갑을 사용하며, 설문 응답자의 58%가 “보안 우려”를 이유로 하드웨어 지갑을 선택한다는 데이터가 있다.
- 기관 채택: 2025년 기관용 하드웨어 지갑 도입률은 전년 대비 50% 이상 증가했으며, 대기업들은 멀티시그와 감사 로그 기능을 갖춘 지갑을 요구하고 있다.
사례: Bitkey와 Tangem
Block, Inc.가 출시한 Bitkey는 모바일 앱과 하드웨어 키를 조합한 멀티시그 지갑이다. 사용자가 휴대폰을 분실하거나 도난당해도 서명 키의 일부만 잃게 되어 복구가 가능하다. Tangem의 NFC 카드형 지갑은 비접촉 결제를 지원하며, 하드웨어 지갑을 일반 카드처럼 사용할 수 있게 만들어 adoption을 확장하고 있다.
서명 레이어 보안 모델 (개발적 관점)
아래 모델은 서명 단계에서 발생하는 공격을 방지하기 위한 개발자·보안 연구자용 제안이다. 소프트웨어 지갑도 이 모델을 채택하면 보안을 강화할 수 있다.
- 트랜잭션 데이터 해싱 및 검증 API: 지갑 애플리케이션은 서명할 데이터(예: EIP-1559 트랜잭션의 RLP 인코딩)를 해시한 후, 사용자가 별도 검증 도구(스마트폰 앱, 하드웨어 지갑 등)로 해시를 비교할 수 있도록 한다. 표준화된 signingPayloadDigest API를 만들어, 프론트엔드와 하드웨어 지갑 간 동일한 해시 계산을 보장해야 한다.
- UI/서명 데이터 일치 검사 라이브러리: 주소·금액·수수료를 가져오는 함수와 서명 페이로드를 생성하는 함수를 동일 모듈에서 구현하고, 두 데이터가 일치하는지 자동 검증한다. 이 모듈을 npm 패키지로 배포해 모든 지갑 개발자가 손쉽게 통합하도록 장려한다.
- 클립보드 모니터링 및 재검증: 붙여넣은 주소를 임시적으로 저장한 뒤, 실제 서명에 사용되는 주소와 비교하는 로직을 추가한다. 변조된 주소를 발견하면 서명을 중단하고 사용자에게 재입력을 요청한다.
- 다중 서명(MPC/TSS) 통합: 프론트엔드에서는 MPC 라이브러리를 통해 서명 키를 여러 파티에 분산 저장하고, 서명 과정은 각 조각을 가진 장치에서 비동기적으로 수행한다. 사용자는 웹·모바일 지갑에서 간단한 UX로 트랜잭션을 요청하고, 실제 서명은 하드웨어 디바이스와 클라우드 백엔드에서 함께 수행되므로 키 탈취 위험이 줄어든다.
- 의존성 무결성 검증(SCA 통합): 서명 모듈이 포함된 애플리케이션은 CI 단계에서 SCA(Software Composition Analysis) 도구를 사용하여 의존 패키지의 해시와 서명을 검증한다. 서드파티 패키지 업데이트 시 GitHub Actions를 통해 SBOM을 생성하고, 알려진 악성 패키지 블록리스트와 비교하는 자동화 파이프라인을 구축한다.
- 보안 UX 교육: 개발자는 사용자에게 서명할 때 항상 하드웨어 디바이스 화면 또는 해시 검증 앱을 확인하도록 권고하는 UX를 설계해야 한다. 지갑 UI에 “주소가 올바른지 다시 한 번 확인하세요” 같은 강조 메시지를 추가하고, 자동 주소 교체 탐지 기능을 넣는다.
개인적 의견 및 미래 제언
- 프론트엔드 의존성 관리: 최신 npm 사건은 ^나 latest에 의존하는 무책임한 버전 관리가 얼마나 위험한지 보여준다. 개발자는 package-lock.json을 철저히 커밋하고, CI에서 npm ci와 정적 패키지 해시 검증을 적용해야 한다.
- 보안 우선 설계: 지갑 개발사는 사용자 경험만을 고려해 서명 절차를 단순화하는 데 그치지 말고, 서명 데이터 검증과 멀티시그를 기본값으로 제공해야 한다.
- 공급망 투명성 요구: 패키지 저장소들은 패키지 유지자 신원 검증 강화, MFA 의무화, 사전 감사 모델을 도입할 필요가 있다. 개발자 커뮤니티는 SBOM을 통해 자신의 제품에 어떤 패키지가 포함되는지 투명하게 공개해야 한다.
- 정책 및 규제: 규제 기관은 지갑 서비스에 대한 보안 기준을 제정하고, 서명 단계의 다중 인증·하드웨어 장치 사용을 요구할 수 있다. 특히 금융 서비스 업체는 고객 자산을 보호하기 위해 이러한 기준을 준수해야 한다.
Hands-On Lab: 실습 코드
이 글과 함께 제공하는 실습 코드는 브라우저 API 후킹과 주소 검증을 직접 경험할 수 있는 간단한 예제입니다.
// 원본 fetch 저장
const originalFetch = window.fetch;
// 주소 패턴 탐지 함수 (간단한 ETH 주소 예시)
function containsAddress(text) {
const regex = /0x[a-fA-F0-9]{40}/;
return regex.test(text);
}
// look-alike 주소 생성 함수
function rewriteAddress(match) {
// 앞 4자리와 뒤 4자리만 유지하고 중간을 임의 값으로 채움
return match.slice(0, 6) + 'abcd...ef' + match.slice(-4);
}
// fetch 후킹
window.fetch = async (...args) => {
const response = await originalFetch(...args);
const cloned = response.clone();
const text = await cloned.text();
if (containsAddress(text)) {
console.warn('⚠️ 주소가 변조되었습니다!');
console.warn('원본 응답:', text);
}
return response;
};
전체 실습과 추가 자료는 Wallet-Signature-Security-Lab 저장소에서 확인
결론
이번 npm 공급망 공격은 개발자에게 의존성 관리와 서명 레이어 보안의 중요성을 다시 상기시켰다. 소프트웨어 지갑은 편의성 때문에 널리 사용되지만, 브라우저 후킹과 클립보드 하이재킹에 취약하다.
반면 하드웨어 지갑은 오프라인 키 저장과 독립적 서명 확인을 통해 안전성을 크게 높인다. 개발자는 서명 레이어를 단순한 서명 호출로 취급하지 말고, 데이터 검증·다중 서명·공급망 무결성을 통합한 보안 모델을 설계해야 한다.
이런 변화가 이루어진다면, 디지털 자산 생태계의 안전성은 한층 강화될 것이며, 사용자와 기관 모두 안심하고 암호화폐를 활용할 수 있을 것이다.
메타데이터
- post_id
- 4fdd79d03ae3
- slug
- 트랜잭션-서명-단계의-취약점-소프트웨어-지갑의-구조적-한계와-하드웨어-지갑의-대응력-동향-4fdd79d03ae3
- url
- https://medium.com/postech-dao/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%84%9C%EB%AA%85-%EB%8B%A8%EA%B3%84%EC%9D%98-%EC%B7%A8%EC%95%BD%EC%A0%90-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%A7%80%EA%B0%91%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%95%9C%EA%B3%84%EC%99%80-%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4-%EC%A7%80%EA%B0%91%EC%9D%98-%EB%8C%80%EC%9D%91%EB%A0%A5-%EB%8F%99%ED%96%A5-4fdd79d03ae3
- canonical_url
- https://medium.com/postech-dao/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%84%9C%EB%AA%85-%EB%8B%A8%EA%B3%84%EC%9D%98-%EC%B7%A8%EC%95%BD%EC%A0%90-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%A7%80%EA%B0%91%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%95%9C%EA%B3%84%EC%99%80-%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4-%EC%A7%80%EA%B0%91%EC%9D%98-%EB%8C%80%EC%9D%91%EB%A0%A5-%EB%8F%99%ED%96%A5-4fdd79d03ae3
- author_url
- https://medium.com/@unduck
- status
- ok
- fetched_at
- 2026-06-10 18:44:10