Bitwarden CLI npm 패키지, GitHub Actions CI/CD 파이프라인 공격으로 악성코드 삽입됨
Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign
TL;DR Highlight
Bitwarden CLI의 npm 패키지(@bitwarden/cli 2026.4.0)가 GitHub Actions CI/CD 파이프라인 침해를 통해 자격증명 탈취 악성코드에 감염됐다. 1천만 명 이상이 사용하는 오픈소스 패스워드 매니저 CLI가 공급망 공격에 당했다는 점에서 npm 보안 전반에 경각심을 주는 사건이다.
Who Should Read
CI/CD 파이프라인에서 npm 패키지를 설치하거나 Bitwarden CLI를 사용하는 개발자 및 DevOps 엔지니어. 특히 GitHub Actions 워크플로우에서 자동으로 의존성을 설치하는 환경을 운영 중인 팀.
Core Mechanics
- 공격 대상이 된 버전은 @bitwarden/cli 2026.4.0이며, 악성 코드는 패키지 내 bw1.js 파일에 삽입됐다. 공격자는 Bitwarden의 GitHub Actions CI/CD 파이프라인을 침해해 빌드 결과물에 페이로드를 심는 방식을 사용했다.
- 이 사건은 Checkmarx 공급망 캠페인(특정 공격 그룹이 npm 생태계를 노리는 연속 공격)의 일부로, 이전에 분석된 mcpAddon.js와 동일한 C2(명령·제어 서버) 엔드포인트(audit.checkmarx[.]cx/v1/telemetry)와 페이로드 구조를 공유한다.
- 악성 페이로드는 GitHub Actions Runner의 메모리를 스크래핑해 GitHub 토큰을 훔치고, ~/.aws/ 파일과 환경변수에서 AWS 자격증명을, azd·gcloud·~/.npmrc에서 Azure/GCP/npm 토큰을, 그리고 Claude/MCP 설정 파일까지 탈취한다.
- 탈취한 npm 토큰으로 피해자가 쓰기 권한을 가진 다른 npm 패키지를 찾아 preinstall 훅에 악성 코드를 주입해 재배포하는 공급망 전파 방식을 사용한다. GitHub에도 Dune 소설 테마 이름({단어}-{단어}-{3자리숫자}) 형태의 공개 저장소를 만들어 암호화된 결과를 커밋한다.
- 러시아어 로케일 킬스위치가 있어, 시스템 locale이 'ru'로 시작하면 조용히 종료된다. Intl.DateTimeFormat().resolvedOptions().locale과 LC_ALL, LC_MESSAGES, LANGUAGE, LANG 환경변수를 확인한다.
- 악성 페이로드는 npm install 시점의 preinstall 훅에서 실행되기 때문에, 설치 후 코드를 검사하는 기존 보안 관행이 무력화된다. 설치 자체가 공격이기 때문에, CI/CD에서 자동 설치가 반복되는 환경은 단시간 노출만으로도 위험하다.
- Bitwarden CLI 자체는 자동 업데이트를 하지 않으므로 피해는 제한적이었고, 영향을 받은 다운로드 수는 약 334건으로 확인됐다. 브라우저 확장, MCP 서버, 기타 공식 배포판은 현재까지 영향 없음.
- ~/.bashrc와 ~/.zshrc에 페이로드를 주입해 셸 재시작 후에도 지속성을 유지하며, Dune 소설의 'Shai-Hulud', 'Butlerian Jihad' 등 이념적 브랜딩이 악성코드 내에 직접 포함된 것이 이전 Checkmarx 캠페인과 다른 점이다.
Evidence
- npm 패키지 설치 시 최소 릴리즈 대기 기간을 설정하면 이런 공격을 방어할 수 있다는 실용적 조언이 공유됐다. npm 11.10+에서 .npmrc에 min-release-age=7(일)을 설정하면 이번 악성 패키지(~19시간 만에 발견·deprecated)뿐 아니라 axios, ua-parser-js 등 단시간에 제거된 이전 사례들도 막을 수 있었을 것이라는 의견이다.
- preinstall 훅이 실행 시점이라는 점이 핵심 문제라는 지적이 있었다. '설치 후 검사'라는 기존 보안 관행이 완전히 무너지며, AI 코딩 어시스턴트나 에이전트가 자동으로 패키지를 설치하는 환경에서는 단 한 번의 설치만으로도 공격이 성립한다는 점에서 더 위험하다는 분석이 나왔다.
- 의존성 고정(pin)의 중요성에 대한 토론이 있었다. lockfile이 있어도 ^(캐럿) 버전 범위를 쓰면 lockfile 업데이트 시 의도치 않은 새 버전이 들어올 수 있으므로, 비즈니스에 치명적인 도구는 정확한 버전을 고정해야 한다는 의견이 나왔다.
- 이 공격이 Claude/MCP 설정 파일까지 탈취 대상으로 삼는다는 점에서, 셸 프로파일 변조를 통해 다음 코딩 어시스턴트가 읽는 컨텍스트를 오염시키는 새로운 공격 벡터가 등장할 수 있다는 우려가 제기됐다.
- 러시아 로케일 킬스위치에 대해 '대담하면서도 비겁하다'는 반응이 있었다. 자국민은 보호하면서 나머지를 공격하는 패턴이 국가 연계 또는 특정 지역 기반 위협 행위자임을 강하게 시사한다는 의견이다.
How to Apply
- npm/pnpm/bun/uv를 사용하는 프로젝트라면 패키지 매니저 설정에 최소 릴리즈 대기 기간을 추가하면 된다. ~/.npmrc에 min-release-age=7, pnpm rc에 minimum-release-age=10080(분), ~/.bunfig.toml에 minimumReleaseAge = 604800(초)을 설정하면 신규 배포 직후 악성 패키지가 자동 설치되는 것을 방지할 수 있다.
- CI/CD 파이프라인에서 npm 패키지를 설치할 때 package.json의 버전 범위를 ^ 없이 정확한 버전으로 고정하고, lockfile을 커밋에 포함시켜야 한다. 특히 시크릿이나 자격증명을 다루는 도구(Bitwarden CLI 등)는 반드시 버전 핀닝을 적용하는 것이 좋다.
- Bitwarden CLI를 현재 사용 중이라면 영향 받은 버전(2026.4.0)을 사용했는지 CI 로그를 확인하고, 해당 워크플로우에서 노출됐을 수 있는 모든 시크릿(GitHub 토큰, AWS/GCP/Azure 자격증명, npm 토큰, SSH 키 등)을 즉시 교체해야 한다. Bitwarden 공식 커뮤니티에서 공개한 피해 시간대를 참고해 노출 여부를 판단하면 된다.
- GitHub Actions를 운영 중이라면 워크플로우에서 사용하는 서드파티 Action의 버전을 SHA 해시로 고정하고, 불필요한 시크릿 접근 권한을 제거해 침해 시 피해 범위를 최소화하는 것이 좋다.
Code Example
# ~/.npmrc (npm 11.10+ 필요)
min-release-age=7 # 단위: 일
# ~/Library/Preferences/pnpm/rc
minimum-release-age=10080 # 단위: 분
# ~/.bunfig.toml
[install]
minimumReleaseAge = 604800 # 단위: 초
# ~/.config/uv/uv.toml (Python uv 패키지 매니저)
exclude-newer = "7 days"Terminology
관련 논문
프로덕션 AI 에이전트를 GPT-5.6으로 마이그레이션: 2.2배 빠르고 27% 저렴
마케팅 웹사이트를 자동 생성하는 프로덕션 AI 에이전트를 Claude Opus 4.8에서 GPT-5.6 Sol로 전환한 실전 경험담으로, 단순 모델 교체가 아니라 eval 하네스, 툴 스키마, 캐싱, 추론 리플레이까지 손봐야 했던 과정을 구체적인 수치와 함께 정리했다.
xAI Grok Build CLI가 xAI 서버로 전송하는 데이터: 네트워크 레벨 분석
xAI의 공식 코딩 CLI 도구 Grok Build가 사용자 동의 없이 전체 Git 저장소와 .env 시크릿 파일을 xAI 서버로 업로드한다는 사실이 네트워크 트래픽 분석으로 밝혀졌다.
중요할 때 기억하라: Long-Horizon 에이전트를 위한 Proactive Memory Agent
LLM 에이전트가 긴 작업 중 중요한 정보를 잊어버리는 문제를 별도의 메모리 에이전트가 '적절한 타이밍에' 끼어들어 해결하는 방법
WebSwarm: 깊고 넓은 웹 검색을 위한 재귀적 Multi-Agent Orchestration
복잡한 웹 검색을 재귀적으로 분해하고 각 노드에 적합한 검색 모드를 동적으로 할당하는 멀티에이전트 프레임워크
웹 앱을 리버스 엔지니어링해서 AI Agent 도구로 자동 변환하기
로그인된 웹 앱의 API 호출을 브라우저에서 감시해 자동으로 MCP 도구로 변환하는 에이전트를 만들었다. 소스 코드나 공식 API 문서 없이도 Jira, Spotify 같은 서비스에 AI 어시스턴트를 붙일 수 있다.
FableCut – AI 에이전트가 조작할 수 있는 브라우저 기반 비디오 에디터 (zero deps)
타임라인 전체를 JSON 파일 하나로 표현하고 MCP/REST로 AI 에이전트가 직접 편집할 수 있는 브라우저 비디오 에디터로, Claude 같은 AI가 프롬프트 하나로 영상을 자동 컷편집하고 결과를 실시간으로 UI에 반영해준다.