5월 14일 14시 25분과 26분(UTC) 사이, node-ipc 9.1.6·9.2.3·12.0.1 세 버전이 npm에 잇달아 올라왔다. 겉보기엔 평범한 업데이트였다. 실제로는 세 버전 모두 자격증명을 훔쳐 DNS로 빼돌리는 백도어가 심겨 있었다. 공급망 공격이라고 하면 흔히 탈취된 npm 토큰이나 타이포스쿼팅 패키지를 떠올리지만, 이번엔 그중 어느 쪽도 아니었다.
통념: 공급망 공격은 토큰이나 가짜 이름으로 뚫린다
node-ipc에는 정식 유지관리자 12명이 등록돼 있다. 이번에 악성 버전을 게시한 계정 "atiertant"도 그중 하나였다. 몇 년째 활동이 없던 계정이라 공격자가 npm 인프라를 직접 뚫었거나 토큰을 훔쳤을 거라 짐작하기 쉽다. 패키지 이름도 그대로였다. node-ipc를 흉내 낸 가짜 패키지가 아니라, 진짜 node-ipc 그 자체가 감염원이었다.
실제: 만료된 도메인 하나가 통로였다
이 계정의 이메일은 유지관리자 개인 도메인(atlantis-software.net)에 연결돼 있었다. 그런데 이 도메인은 2025년 1월 10일 만료된 채 방치돼 있었다. 공격자는 2026년 5월 7일 이 도메인을 네임칩(Namecheap)에서 재등록하고, 같은 서비스의 이메일 기능으로 메일함을 새로 열었다. 그다음엔 npm의 정상적인 비밀번호 재설정 절차를 그대로 밟았을 뿐이다. 인프라 침투도, 토큰 탈취도 필요 없었다. 죽은 도메인 하나가 살아있는 계정 권한 전체로 이어진 셈이다.
무엇을 훔쳤나
백도어는 누군가 코드에서 require("node-ipc")를 실행하는 순간 작동했다. 별도 프로세스를 띄워 환경변수, 시스템 정보, /etc/hosts, 그리고 AWS·GCP·Azure 인증정보, SSH 키, 쿠버네티스 토큰, .npmrc, 깃 자격증명, 테라폼 상태 파일, DB 비밀번호, 셸 히스토리, 브라우저 쿠키, 도커 설정, 심지어 Claude Code 같은 AI 코딩 도구의 세션 정보까지 수십 종의 파일을 훑었다.
훔친 데이터는 압축한 뒤 곧바로 인터넷으로 보내지 않았다. 대신 잘게 쪼개 DNS 조회 요청의 도메인 이름 일부로 위장해 내보냈다. 공격자가 관리하는 네임서버는 그 조회 기록만 모아두면 원본 데이터를 재조립할 수 있었다. 방화벽 대부분이 DNS 트래픽 자체는 차단하지 않는다는 맹점을 그대로 노린 방식이다.
3분 만에 잡힌 이유
이렇게 정교하게 짠 침투 경로와 달리, 발각은 순식간이었다. 오픈소스 패키지의 신규 게시를 실시간으로 감시하는 Socket의 자동 악성코드 스캐너가 게시 약 3분 만에 세 버전을 전부 잡아냈다. 이후 BleepingComputer·The Hacker News·Snyk 등이 뒤이어 분석을 내놨다. 다만 이 사건에 대한 공식 CVE나 GitHub 보안 권고(GHSA)는 이 글 작성 시점까지 별도로 등록되지 않았다.
node-ipc, 이번이 처음은 아니다
node-ipc는 이미 한 차례 유명해진 이력이 있다. 2022년, 당시 유지관리자였던 브랜든 노자키 밀러가 우크라이나 전쟁에 항의하는 뜻으로 러시아·벨라루스 IP 사용자의 파일을 지우는 코드를 몰래 심었던 사건이다(). 이번 백도어는 그 사건과는 무관하다. 정치적 메시지도 없고, 원래 그 유지관리자가 관여하지도 않았다. 몇 년째 잠들어 있던 다른 공동 유지관리자 계정이 도메인 만료라는 전혀 다른 경로로 뚫린, 순수 금전 목적의 별개 사건이다.
실용 관점
이번 사건이 국내에서 별도로 보도된 사례는 확인되지 않았다. 그렇다고 안전한 건 아니다. node-ipc는 과거 Vue CLI 의존성 체인에도 포함됐던 만큼, npm 생태계를 쓰는 국내 개발팀도 똑같이 노출 대상이다. 팀 차원에서 할 수 있는 대응은 명확하다. package-lock.json으로 버전을 고정해 예고 없는 마이너 업데이트가 그대로 설치되는 걸 막고, 의존성 스캐너로 신규 게시 버전의 이상 행위를 자동 탐지하는 체계를 갖추는 게 현실적인 대안이다.