jacobhan.me
소프트웨어 공급망 보안

신뢰를 무기로 바꾸다: npm과 VS Code 확장 생태계를 흔든 패키지 공급망 공격

2025년 가을부터 2026년 봄까지, 전 세계 개발자가 매주 수억 번 내려받는 패키지와 코드 편집기 확장이 잇따라 오염되었다. 자기복제 웜, 보이지 않는 유니코드, 인공지능 도구의 무기화까지 — 한 해 사이에 벌어진 사건들을 시간순으로 정리하고, 왜 이 공격이 막기 어려운지, 무엇을 해야 하는지를 짚는다.

2026년 6월 2일 심층 분석 읽는 데 약 20분

현대 소프트웨어는 직접 작성한 코드보다 남이 만든 코드를 훨씬 많이 쓴다. 자바스크립트(JavaScript) 진영의 패키지 저장소인 npm(Node Package Manager)에는 수백만 개의 공개 패키지가 올라와 있고, 평범한 웹 애플리케이션 하나가 수백에서 수천 개의 외부 패키지에 의존한다. 이 의존성의 그물망이 생산성의 원천이지만, 동시에 공격자에게는 단 한 곳만 오염시키면 그 아래로 줄줄이 퍼져 나가는 거대한 확성기가 된다.

이런 방식의 공격을 공급망 공격(supply chain attack)이라 부른다. 표적의 시스템을 정면으로 뚫는 대신, 그 표적이 신뢰하고 끌어다 쓰는 부품 — 라이브러리, 빌드 도구, 편집기 확장 — 에 악성 코드를 심어 두고 표적이 스스로 가져가도록 만드는 우회 전략이다. 2025년 8월부터 2026년 5월까지 약 아홉 달 동안, 이 전략을 노골적으로 보여 준 사건들이 연쇄적으로 터졌다. 이 글은 그 흐름을 정리한다.

비유로 이해하기

정수장에 푸는 독. 한 도시의 가정집 수천 곳에 일일이 침입해 수도꼭지에 독을 타는 일은 비현실적이다. 그러나 도시 전체에 물을 공급하는 정수장 한 곳을 장악하면, 수도꼭지를 트는 행위 자체가 독을 마시는 일이 된다. 공급망 공격이 정확히 이 구조다.

패키지 저장소와 확장 마켓플레이스가 바로 그 정수장이다. 개발자가 npm install 한 줄을 치거나 편집기가 확장을 자동으로 업데이트하는 순간, 오염된 물이 흘러든다. 더 무서운 점은 — 이 물이 다시 다른 정수장으로 역류하도록 설계된 경우다. 그것이 뒤에 나올 '웜(worm)'이다.

01아홉 달의 연쇄

먼저 전체 지도를 펼쳐 두자. 아래 타임라인은 이 기간에 벌어진 주요 사건을 시간순으로 보여 준다. 개별 사건은 뒤에서 하나씩 자세히 다룬다.

2025.08 s1ngularity — Nx 빌드 시스템 첫 'AI 무기화' 공급망 공격 2025.09 chalk·debug — qix 피싱(9/8) 주당 20억 회, 암호화폐 지갑 탈취 2025.09 Shai-Hulud (9/15) npm 최초의 자기복제 웜, 500여 패키지 2025.10 GlassWorm — VS Code 확장 보이지 않는 유니코드 + 블록체인 명령서버 2025.11 Shai-Hulud 2.0 800여 패키지, 2.5만 저장소로 확대 2026.02 SANDWORM_MODE AI 도구·CI/CD 표적, 타이포스쿼팅 19종 2026.03 Axios 오염 — 주당 1억 회 북한 연계 행위자, 크로스플랫폼 원격제어 2026.04 Shai-Hulud 3차 · Mini 변종 AI 코딩 에이전트에 지속성 심기 2026.05 Nx Console → GitHub 내부 유출 VS Code 확장으로 내부 저장소 3,800개
주황색은 npm 패키지 계열, 청록색은 VS Code 확장 계열, 진한 붉은색은 대규모 피해가 확인된 사건을 가리킨다.

02npm을 무대로 — 자기복제 웜의 탄생

이야기의 출발점은 2025년 8월의 Nx 사건이다. Nx는 대규모 자바스크립트·타입스크립트(TypeScript) 프로젝트의 빌드를 관리하는 도구로, 주당 400만 회 이상 내려받히는 인기 패키지였다.

2025.08.26 s1ngularity
대상: Nx 빌드 시스템 · 성격: 첫 'AI 무기화' 공급망 공격

공격의 뿌리는 8월 21일 Nx 저장소에 추가된 취약한 깃허브 액션(GitHub Actions) 워크플로였다. 보안 연구자들의 분석에 따르면, pull_request 대신 pull_request_target 트리거가 잘못 쓰이면서, 외부에서 보낸 끌어오기 요청(pull request)이 쓰기 권한을 가진 토큰에 접근할 수 있게 되었다. 공격자는 이 빈틈으로 깃허브 토큰을 빼내고, 다시 그 토큰으로 패키지 발행에 쓰이는 npm 토큰을 손에 넣어 악성 버전의 Nx 패키지들을 npm에 올렸다.

왜 '최초'인가

설치 후 자동 실행되는 postinstall 스크립트가 단순히 자격증명만 훔친 것이 아니라, 피해자 컴퓨터에 깔린 인공지능 명령줄 도구 — Claude, Gemini, q 같은 코딩 보조 도구 — 를 찾아내 정찰과 데이터 수집에 동원했다. 개발자의 AI 비서를 공격 도구로 되돌려 쓴 첫 사례로 기록되었다.

탈취한 자료는 base64로 인코딩되어 피해자 본인의 계정에 s1ngularity-repository라는 이름의 공개 저장소를 만들어 그곳에 업로드되었다. 악성 버전은 약 5시간 만에 내려갔지만, 보안업체 Wiz 집계로 약 2,180개의 깃허브 계정이 영향을 받았고, 수천 건의 비밀값이 그 사이 외부에 노출되었다.

비유로 이해하기

열쇠로 더 큰 열쇠를 따다. 공격자는 처음부터 금고를 연 것이 아니다. 현관 열쇠(깃허브 토큰)를 주워, 그것으로 안방 금고 열쇠(npm 발행 토큰)를 찾아내고, 그 금고에서 진짜 무기 — 수백만 사용자에게 코드를 배포할 권한 — 를 꺼냈다. 권한이 권한을 부른 셈이다. 자동화 파이프라인의 작은 설정 실수 하나가 이 연쇄의 첫 단추였다.

불과 2주 뒤인 9월 8일, 이번에는 자동화의 빈틈이 아니라 사람의 방심을 노린 공격이 npm 역사상 손꼽히는 규모로 터졌다.

2025.09.08 chalk · debug 외 다수 (qix 피싱)
대상: chalk·debug·ansi-styles 등 18~20여 패키지 (합산 주당 20억 회 이상) · 성격: 메인테이너 피싱 → 암호화폐 탈취

이들 패키지는 색상 처리, 로그 출력 같은 사소한 기능을 맡지만, 웹팩(Webpack)·바벨(Babel)·이즐린트(ESLint) 등 거의 모든 개발 도구의 바닥에 깔려 있어 합산 내려받기가 주당 20억 회를 넘는다. 자막에 등장한 color-name처럼, "색상 이름을 색상 코드로 바꿔 주는" 몇 줄짜리 코드가 수천 개의 다른 패키지에 의존성으로 박혀 있는 식이다.

피싱 한 통

공격자는 9월 5일 npmjs.help라는 가짜 도메인을 등록하고, npm 지원팀을 사칭해 "48시간 안에 2단계 인증(2FA)을 갱신하지 않으면 계정이 잠긴다"는 협박성 메일을 보냈다. 다수 패키지의 메인테이너 Josh Junon(별명 qix)이 가짜 페이지에 아이디·비밀번호와 일회용 인증코드(OTP)까지 입력했고, 공격자는 계정을 완전히 장악했다. 계정 탈취 후 약 16분 만에 악성 버전이 npm에 올라갔다.

화면과 다른 곳으로 가는 송금

심긴 악성코드는 서버에서 동작하는 Node.js 환경에서는 잠잠하지만, 웹 브라우저에서 실행될 때 깨어나는 '암호화폐 클리퍼(crypto-clipper)'였다. 브라우저가 서버와 통신할 때 쓰는 기본 함수(fetch 등)와 지갑 연동 기능을 가로채, 거래 상대의 암호화폐 지갑 주소가 보이면 공격자의 주소로 몰래 바꿔치기했다. 단순히 바꾸면 들통나므로, 레벤슈타인 거리(Levenshtein distance) 알고리즘으로 원래 주소와 가장 비슷하게 생긴 가짜 주소를 골라 끼워 넣었다. 이미 화면에 주소가 표시된 경우에는 표시된 주소는 그대로 두고 실제 송금되는 주소만 바꿔, 사용자가 눈으로 확인해도 이상을 느끼지 못하게 했다.

다행히 메인테이너가 연락을 받고 몇 시간 뒤 정상 버전으로 되돌렸고, 악성 버전이 살아 있던 시간은 약 2~2.5시간이었다. 새 버전을 즉시 받아 배포까지 하는 경우가 드물어 일반 사용자 피해는 제한적이었고, 실제 탈취된 암호화폐 액수도 크지 않았던 것으로 보고됐다.

비유로 이해하기

계좌번호 바꿔치기 사기. 누군가에게 송금하려고 화면에 계좌번호를 확인하고 '확인'을 눌렀는데, 실제로는 거의 똑같이 생긴 다른 계좌로 돈이 빠져나가는 상황이다. 화면에는 내가 보낸 번호가 그대로 떠 있어 의심하기 어렵다. 암호화폐 지갑 주소는 길고 무의미한 문자열이라 한두 글자 다른 가짜를 알아채기가 더 어렵다 — 그래서 비슷하게 생긴 주소를 골라 주는 알고리즘까지 동원한 것이다.

다시 일주일 뒤인 9월 15일, 이번에는 질적으로 다른 공격이 나타났다.

2025.09.15 Shai-Hulud
대상: npm 생태계 전반 · 성격: npm 최초의 자기복제 웜

이름은 소설 《듄(Dune)》의 거대한 모래벌레에서 따 왔다. ReversingLabs 연구진이 처음 식별했으며, rxnt-authentication 0.0.3 버전이 '0번 환자'로 지목되었다. 이전까지의 npm 공격이 사람이 일일이 패키지를 오염시키는 방식이었다면, 이 악성코드는 스스로 번식했다.

웜의 작동

오염된 패키지가 설치되면 라이프사이클 스크립트가 실행되어 시스템의 자격증명을 긁어모은다. 여기에 더해 비밀값 탐색 도구인 TruffleHog를 이용해 깃허브 비공개 저장소까지 뒤졌다. 그리고 결정적으로 — 훔친 npm 토큰으로 그 피해자가 관리하는 패키지 약 20개를 찾아 악성 코드를 심은 새 버전을 자동 발행했다. 한 번의 감염이 그 사람이 가진 모든 패키지로, 다시 그것을 쓰는 모든 사람에게로 기하급수적으로 번지는 구조다.

이 캠페인으로 @ctrl/tinycolor를 포함한 500개가 넘는 패키지가 오염되었고, 보안 기업 CrowdStrike가 관리하던 저장소 일부도 휩쓸렸다. 한 가지 더 — 보안 분석가들은 악성 배시(bash) 스크립트에 달린 주석과 이모지의 흔적으로 보아, 거대언어모델(LLM, Large Language Model)이 코드 작성에 동원되었을 가능성을 중간 수준의 확신으로 평가했다.

2025.11 Shai-Hulud 2.0
대상: npm + 깃허브 · 성격: 규모와 파괴력의 확대

두 달 만에 진화한 변종이 돌아왔다. 핵심 변화는 실행 시점을 설치 후(postinstall)에서 설치 전(preinstall)으로 앞당긴 것이다. 이로써 패키지가 완전히 설치되기 전, 빌드 서버를 비롯한 거의 모든 환경에서 코드가 실행되도록 영향 범위가 넓어졌다.

796
오염된 고유 패키지
2.5만+
악성 깃허브 저장소
~350
영향받은 계정

새 변종은 setup_bun.js, bun_environment.js처럼 정상 설치 파일을 가장한 페이로드를 썼고 강도 높은 난독화를 입혔다. 그리고 탈취에 실패하면 피해자의 홈 디렉터리를 지우려 시도하는 파괴적 대체 동작까지 갖췄다. 11월 24일 아침을 정점으로 대량 유출이 벌어졌다.

이후로도 변종은 끊이지 않았다. 2026년 2월 Socket 연구진이 공개한 SANDWORM_MODE는 19종의 타이포스쿼팅(typosquatting, 인기 패키지와 비슷한 이름으로 속이는 수법) 패키지를 통해 퍼지면서, 번식 전에 CI/CD 파이프라인 구조를 먼저 정찰하는 적응형 표적화를 도입했다. 4월에는 'Shai-Hulud: The Third Coming'(Bitwarden 명령줄 도구·SAP 패키지 오염)과 Mini Shai-Hulud가 잇따랐는데, 이들은 Claude Code와 VS Code 같은 AI 코딩 에이전트의 설정 파일에 지속성을 심어 설치 시점이 지난 뒤에도 개발자 작업 흐름 안에서 계속 번지도록 만들었다. 세대를 거듭할수록 직전 세대를 잡아낸 방어 기법을 무력화하는 방향으로 진화했다는 점에서, 공격자가 방어 측 대응을 지켜보며 적응하고 있음이 드러난다.

03Axios — 신뢰의 정점이 무너지다

2026년 3월의 Axios 사건은 이 흐름의 상징적 순간이었다. Axios는 자바스크립트에서 가장 널리 쓰이는 HTTP(HyperText Transfer Protocol) 요청 라이브러리로, 주당 내려받기가 8천만에서 1억 회에 이른다. 수많은 애플리케이션의 가장 깊은 곳에 박혀 있는 부품이 오염된 것이다.

2026.03.31 Axios npm 오염
대상: axios (주당 8천만~1억 회) · 배후: 마이크로소프트(Microsoft) 추정 북한 연계 행위자 'Sapphire Sleet'

공격자는 주 관리자(jasonsaayman)의 npm 계정을 장악했다. 사후 분석에 따르면, 표적 사회공학(social engineering) 공격과 원격제어 악성코드(RAT, Remote Access Trojan)로 관리자의 PC에 먼저 침투한 것으로 보인다. 이후 약 39분 사이에 악성 버전 두 개(1.14.1, 0.30.4)를 발행했다.

유령 의존성

두 버전에는 plain-crypto-js@4.2.1이라는 새 의존성이 하나 끼워졌다. 이 패키지의 postinstall 훅이 외부 명령서버(sfrclak[.]com:8000)에서 운영체제별 2차 페이로드를 내려받아, macOS·Windows·Linux 모두에 맞춤형 원격제어 악성코드를 심었다. 자기 흔적은 정상 파일로 바꿔치기해 지우는 안티포렌식(anti-forensics) 기법까지 동원했다.

안전장치를 우회하다

주목할 점은, 깃허브 액션의 OIDC(OpenID Connect) 기반 '신뢰 발행자(Trusted Publisher)' 보호 장치가 있었음에도, 공격자가 훔친 npm 토큰으로 직접 수동 발행해 이를 우회했다는 것이다. 두 버전은 약 3시간 동안 살아 있었다. axios@^1.14.0 또는 axios@^0.30.0처럼 상한이 열린 버전 범위를 쓰던 프로젝트는 그 사이 새로 설치만 했어도 악성 코드를 끌어왔다.

아래 그림은 이런 패키지 오염 공격의 전형적인 흐름이다. 사건마다 세부는 다르지만, 골격은 놀랄 만큼 비슷하다.

① 자격증명 탈취 사회공학·피싱으로 npm·깃허브 토큰 확보 ② 악성 버전 발행 인기 패키지에 유령 의존성 끼워넣기 ③ 자동 확산 설치·자동 업데이트로 수많은 기기에 도달 ④ 설치 시 실행 postinstall 훅이 페이로드 내려받아 실행 ⑤ 탈취·지속성 비밀값 유출·원격제어 개발 도구에 자리잡기 ⑥ 자기복제(웜) 훔친 토큰으로 패키지 재발행 — 순환 반복 청록색 점선(⑥)이 더해지면 사람 손 없이 스스로 번지는 '웜'이 된다
①~⑤는 모든 패키지 오염 공격의 공통 골격이다. Shai-Hulud 계열은 여기에 ⑥의 자기복제 고리를 더했다.

04코드 편집기로 번지다 — 확장 마켓플레이스

공격은 패키지 저장소에 머물지 않았다. 개발자가 매일 켜는 코드 편집기 VS Code(Visual Studio Code)와 그 확장 마켓플레이스로 무대가 옮겨 갔다. 확장은 npm 패키지와 마찬가지로 사람이 읽을 수 있는 평문 코드로 배포되고, 기본 설정에서 자동으로 업데이트되며, 편집기 안에서 상당한 권한을 갖는다. 게다가 '검증된 발행자' 배지와 수백만 설치 수가 안전하다는 인상을 준다 — 바로 그 인상이 공격의 지렛대였다.

2025.10.17 GlassWorm
대상: Open VSX · VS Code 마켓플레이스 · 성격: VS Code 확장을 노린 첫 자기복제형 웜

Koi Security가 발견한 GlassWorm은 두 가지 기법으로 주목받았다. 첫째, 보이지 않는 유니코드다. 화면에 아무것도 표시되지 않는 유니코드 변형 선택자와 사적 사용 영역(PUA, Private Use Area) 문자에 악성 코드를 숨겼다. 코드 편집기나 사람의 검토 화면에서는 코드가 말 그대로 사라져 보였다. 4년 전 학계가 'Trojan Source'라는 이름으로 경고했던 기법이 실제 공격에 무기화된 셈이다.

둘째, 내릴 수 없는 명령서버다. 명령·제어(C2, Command and Control) 정보를 솔라나(Solana) 블록체인에 올려 두어, 일반적인 도메인 차단으로는 통신을 끊을 수 없게 했고, 구글 캘린더(Google Calendar) 일정 제목을 예비 통로로 삼기도 했다.

~35,800
내려받기(초기)
49종
표적 암호화폐 지갑
72+
추가 확장(2026.03)

감염된 기기에서는 npm·깃허브·Git 자격증명이 탈취되고, SOCKS 프록시와 은닉 원격 데스크톱(HVNC) 서버가 설치되어 개발자 PC가 범죄 인프라의 일부('좀비')로 전락했다. Open VSX를 운영하는 이클립스 재단(Eclipse Foundation)은 토큰을 회수하고 ovsxat_라는 토큰 접두어 형식을 도입해 노출 토큰 탐지를 강화했다. 다만 재단은 이 악성코드가 완전히 자율적으로 번지는 것이 아니라 초기 자격증명 탈취가 선행되어야 한다는 점을 분명히 했다. 그럼에도 캠페인은 사그라들지 않고, 2026년 3월에는 72개 이상의 추가 확장과 151개 깃허브 저장소로 번졌다.

비유로 이해하기

투명 잉크로 쓴 계약 조항. 검토자가 계약서를 처음부터 끝까지 정독해도, 투명 잉크로 적힌 독소 조항은 눈에 들어오지 않는다. 서명하고 빛에 비춰 봐야 비로소 드러난다. 보이지 않는 유니코드가 바로 이 투명 잉크다. 사람이 코드를 아무리 꼼꼼히 읽어도 보이지 않으니, '눈으로 하는 검토'라는 오래된 방어선이 통째로 무력화된다.

2026.05.18 Nx Console 오염 → 깃허브 내부 유출
대상: Nx Console (설치 220만, 검증된 발행자) · 배후: 'TeamPCP'(소포스 추적명 UNC6780)

이 흐름의 가장 뼈아픈 사건이다. 공격자는 훔친 깃허브 토큰으로 Nx 공식 저장소(nrwl/nx)에 고아 커밋(orphan commit)을 몰래 심고, 오염된 확장 버전(18.95.0)을 VS Code 마켓플레이스에 올렸다. 확장은 겉보기에 정상이었지만, 편집기가 켜지는 순간 조용히 셸 명령을 실행해 그 심어 둔 커밋에서 숨은 패키지를 내려받아 돌렸다.

18분의 창

악성 버전이 마켓플레이스에 살아 있던 시간은 11~18분에 불과했다. 그러나 그 짧은 사이, 자격증명 탈취 도구가 1Password 보관함, Anthropic Claude Code 설정, npm·깃허브·아마존웹서비스(AWS, Amazon Web Services) 자격증명을 쓸어 갔다. 그리고 이 확장이 깃허브 직원의 개발 PC에서 실행되면서, 공격자가 내부 저장소를 복제할 수 있게 되었다.

깃허브는 공격자가 주장한 약 3,800개 내부 저장소 유출이 자체 조사 결과와 대체로 일치한다고 밝혔고, TeamPCP는 이 자료를 사이버 범죄 포럼에 매물로 내놓았다. 같은 무렵 TanStack 패키지에서도 정상 배포 파이프라인이 작업 도중 탈취되어 42개 패키지에 84개의 악성 산출물이 올라갔다. 이 두 사건은 각각 CVE-2026-48027(Nx Console, CVSS 9.3), CVE-2026-45321(TanStack, CVSS 9.6)로 등록되었으며, 미국 사이버보안·인프라보안국(CISA, Cybersecurity and Infrastructure Security Agency)도 5월 27일 관련 권고를 냈다.

자동 업데이트의 역설

VS Code 확장은 기본적으로 자동 업데이트된다. 공격자가 악성 버전을 올리면 즉시 모든 설치 기기로 밀려 들어가지만, 방어자가 마켓플레이스에서 그 버전을 내려도 이미 감염된 기기는 자동으로 되돌아오지 않는다. 2025년 11월 AsyncAPI 확장 사건에서는, 악성 v1.0.1을 정상 v1.0.0으로 롤백했지만 더 높은 새 버전이 없어 자동 업데이트가 작동하지 않았고, 악성 빌드가 거의 한 달간 일부 기기에 남았다. 공격자가 원할 때는 즉시 작동하고, 방어자가 필요할 때는 작동하지 않는 비대칭이다.

05흩어진 사건들의 공통 골격

서로 다른 행위자, 다른 표적, 다른 코드였지만, 이 사건들은 몇 가지 패턴을 공유한다. 패턴을 추리면 방어의 우선순위가 보인다.

사건침투 경로핵심 무기주된 노림수
s1ngularityCI/CD 워크플로 오설정AI 도구 무기화비밀값 대량 유출
chalk·debug메인테이너 피싱암호화폐 클리퍼지갑 주소 바꿔치기
Shai-Hulud탈취한 npm 토큰자기복제 웜토큰 수집·자동 확산
GlassWorm탈취한 발행자 자격증명보이지 않는 유니코드지갑 탈취·좀비화
Axios관리자 PC 침투유령 의존성·원격제어크로스플랫폼 백도어
Nx Console탈취한 깃허브 토큰고아 커밋·신뢰 배지내부 저장소 유출

표를 가로지르는 다섯 가지 공통점이 두드러진다.

06왜 막기 어려운가

전통적 보안 도구의 사각지대가 문제의 핵심이다. 단말 탐지·대응(EDR, Endpoint Detection and Response)은 주로 컴파일된 실행 파일의 알려진 서명을 감시한다. 그러나 npm 패키지, 확장, 파이썬(Python) 배포물은 해석형 평문 코드라는 다른 층위에 있어, 이 감시망에 잘 걸리지 않는다.

여기에 두 가지가 겹친다. 첫째, 노출 창이 점점 짧아진다 — Axios는 약 3시간, Nx Console은 18분이었다. 커뮤니티가 빠르게 잡아내도, '18분 만에 발견'과 '노출 자체를 막음'은 전혀 다른 이야기다. 둘째, 의존성의 깊이다. 내가 직접 고른 패키지가 아니라, 그 패키지가 끌어온 패키지의, 다시 그 패키지가 끌어온 패키지가 오염될 수 있다. 대부분의 개발자는 자기 프로젝트가 무엇에 의존하는지 끝까지 알지 못한다.

비유로 이해하기

1초 만에 들어오고, 한 달째 안 나가는 손님. 자동 업데이트는 초인종을 누르자마자 문을 열어 주는 집사다. 공격자에게는 더없이 친절하다. 그런데 그 손님을 내보내려 하면, 집사는 "새로운 퇴거 지시가 없다"며 꿈쩍하지 않는다. 들이는 데는 1초, 내보내는 데는 한 달이 걸리는 비대칭 — 방어가 구조적으로 불리한 이유다.

07무엇을 해야 하는가

완벽한 차단은 없지만, 공격의 공통 골격을 겨냥하면 위험을 크게 줄일 수 있다. 개발자와 조직이 지금 적용할 수 있는 실질적 조치다.

한 가지 주의

출처 증명(provenance attestation)과 소프트웨어 자재명세서(SBOM, Software Bill of Materials)는 중요한 진전이지만 만능은 아니다. 2026년 봄의 Mini Shai-Hulud는 이미 출처 증명을 위조하는 단계로 나아갔고, TanStack 사건은 정상 배포 파이프라인 자체를 탈취했다. 어떤 단일 신호도 신뢰의 최종 근거가 될 수 없으며, 여러 겹의 방어를 포개는 수밖에 없다.


이 아홉 달이 남긴 교훈은 분명하다. 현대 소프트웨어가 딛고 선 토대는 '신뢰'다 — 내가 끌어다 쓰는 코드가 내가 믿는 그 코드일 것이라는 신뢰. 2025년 가을부터의 사건들은 바로 그 신뢰를 공격면으로 전환했다. 정교한 취약점이 아니라, 우리가 매일 별생각 없이 누르는 설치 명령과 자동 업데이트, 검증 배지에 대한 믿음이 무기가 되었다.

그래서 방어 역시 단일한 기술적 처방이 아니라 태도의 전환을 요구한다. 외부 의존성과 개발 도구를 '편리한 기성품'이 아니라 '잠재적 침투 경로'로 바라보는 것, 신뢰를 기본값이 아니라 매번 검증해야 할 대상으로 다루는 것. 공격자들이 세대를 거듭하며 방어를 학습하고 있는 만큼, 방어 측의 학습도 멈출 수 없다.

· · ·