9월 8일, NPM 생태계에 대규모 소프트웨어 공급망 공격이 발생하여 널리 사용되는 여러 JavaScript 라이브러리가 해킹되었습니다. 이번 보안 사고는 Ledger의 최고 기술 책임자(CTO)인 Charles Guillemet이 신뢰받는 개발자의 Node Package Manager 계정이 탈취되었다고 경고하면서 처음 수면 위로 드러났습니다. 초기 추정치로는 10억 회 이상의 다운로드가 노출된 것으로 보였으나, 추가 분석 결과 실제 피해를 입은 패키지의 주간 다운로드 수는 26억 회를 상회하는 것으로 밝혀졌습니다.

Supply Chain Attack Exposes Over 2 Billion
Supply Chain Attack Exposes Over 2 Billion
이번 공격은 chalk, strip-ansi, color-convert, debug 등 여러 인기 JavaScript 라이브러리를 유지 관리하는 "qix"라는 개발자의 계정을 표적으로 삼았습니다. 이 라이브러리들은 서버 사이드와 프론트엔드 환경을 아우르는 수많은 프로젝트에서 사용됩니다. 공격자들은 가짜 지원 이메일을 통해 접근 권한을 얻은 뒤, 약 18개의 패키지에 악성 업데이트를 배포했습니다. 자동화된 의존성 설치 기능으로 인해 악성코드는 몇 시간 만에 빠르게 확산되었습니다.
Guillemet은 악성코드가 트랜잭션 도중 암호화폐 지갑 주소를 몰래 교체했다고 설명했습니다. 소프트웨어 지갑을 사용하는 유저들은 변경된 수신 주소를 인지하지 못한 채 트랜잭션을 승인할 경우 자산을 잃을 위험에 처했습니다.
Malware Crypto Clipper and MetaMask
보안 연구원들은 이 악성코드를 "크립토 클리퍼(crypto clipper)"로 분류했습니다. 이는 트랜잭션의 여러 단계에서 지갑 주소를 교체합니다. 감지된 지갑이 없을 경우, 악성코드는 fetch 및 XMLHttpRequest와 같은 브라우저 기능을 후킹하여 탈중앙화 애플리케이션 내의 발신 데이터를 수정하고, 애플리케이션 데이터 내의 주소를 스캔하여 변조합니다.
MetaMask와 같은 지갑 확장 프로그램이 설치되어 있으면, 악성코드는 서명 전 트랜잭션을 가로챕니다. 메모리 내의 지갑 주소를 수정하여 유저가 트랜잭션을 검토할 때 사기성 주소가 나타나도록 합니다. 악성코드는 Levenshtein 알고리즘을 사용하여 원본과 매우 유사한 주소를 생성하므로 변조 사실을 알아차리기 더욱 어렵습니다.

Supply Chain Attack Exposes Over 2 Billion
First Signs of the Attack
개발자들은 빌드 시스템에서 예상치 못한 오류 메시지가 반환되면서 공격을 처음 감지했습니다. error-ex라는 의존성을 검사한 결과, Ethereum 지갑을 표적으로 삼는 checkethereumw라는 의심스러운 함수가 포함된 난독화 코드가 발견되었습니다. 분석가들은 해당 악성코드가 Bitcoin, Ethereum, Solana, Tron, Litecoin, Bitcoin Cash를 포함한 여러 블록체인의 지갑 주소에 대한 참조를 포함하고 있음을 확인했습니다.
영향을 받은 패키지 중에는 JavaScript 생태계에서 가장 널리 사용되는 것들이 포함되어 있습니다. Chalk는 주간 다운로드 3억 회 이상, debug는 3억 5천만 회 이상, strip-ansi는 2억 6천만 회 이상을 기록하고 있습니다. 결과적으로 공격받은 라이브러리들의 주간 다운로드 합계는 26억 회가 넘어, 개발자 커뮤니티 전반에 미친 영향의 규모를 짐작게 합니다.
Hardware vs Software Wallets
감염된 라이브러리 중 다수는 암호화폐 프로젝트와 직접적인 관련이 없지만, 의존성 체인에 통합되어 있어 관련 없는 애플리케이션까지 노출되었을 가능성이 있습니다. 암호화폐 지갑 및 탈중앙화 애플리케이션과 상호작용하는 프로젝트들이 가장 높은 위험에 처해 있습니다.
Guillemet은 클리어 사이닝(clear-signing) 기능을 갖춘 하드웨어 지갑 사용자는 승인 전 모든 트랜잭션을 검증할 수 있기 때문에 안전하다고 언급했습니다. 소프트웨어 지갑 유저는 더 큰 위험에 노출되어 있으므로, 의존성이 완전히 검토되고 보안이 확보될 때까지 각별한 주의가 필요합니다.
Finding the Attacker and Funds Stolen
공격자의 암호화폐 주소는 식별되었으며, 공개 블록체인 투명성을 통해 적극적으로 모니터링되고 있습니다. 이번 범행과 연결된 주요 Ethereum 주소는 0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976이며, 여러 개의 백업 주소도 확인되었습니다. 보고 시점까지 탈취된 자금은 이동되지 않았습니다. 이러한 모니터링을 통해 지속적인 분석이 가능하지만, 도난당한 자산의 전체 규모는 아직 불분명합니다.

Supply Chain Attack Exposes Over 2 Billion
JavaScript and Community Role
JavaScript 및 web3 커뮤니티는 이번 사건을 수습하기 위해 빠르게 움직였습니다. 공격받은 패키지의 악성 버전은 대부분 레지스트리에서 제거되었으나, lockfile 내에 구버전을 여전히 의존하고 있는 프로젝트에는 위험이 남아 있습니다. 개발자들은 의존성을 감사하고, 안전한 버전을 고정하며, 추가 노출을 방지하기 위해 깨끗한 빌드를 재설치할 것을 권고받고 있습니다.
보안 전문가들은 개발자들에게 자격 증명을 주기적으로 변경하고, NPM 및 GitHub와 같은 계정에 2단계 인증을 강제하며, 엄격한 버전 관리를 위해 npm ci와 같은 결정론적 설치 방식을 사용할 것을 권장합니다. 유저들은 특히 소프트웨어 지갑을 사용할 때 모든 암호화폐 트랜잭션을 신중하게 검증해야 합니다.
Final Thoughts
이번 사건은 NPM 생태계를 강타한 가장 광범위한 보안 사고 중 하나로 기록될 것입니다. 커뮤니티의 대응은 비교적 신속했지만, 이번 공격은 현대 소프트웨어 공급망의 취약성과 오픈 소스 구성 요소에 대한 광범위한 의존성이 초래하는 위험을 여실히 드러냈습니다.
Guillemet이 강조했듯이, 서명 전 모든 트랜잭션을 검토하는 것은 필수적입니다. 이번 침해 사고는 애플리케이션 인프라 깊숙이 내장된 작은 라이브러리조차도 공격당할 경우 심각한 공격 벡터가 될 수 있음을 보여줍니다. 개발자와 유저 모두에게 지속적인 경계심은 이제 web3 및 소프트웨어 개발 생태계에서 보안을 유지하기 위한 핵심 요소가 되었습니다.



