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
관련 논문
Lathe – LLM으로 새 도메인을 직접 배우는 튜토리얼 생성 CLI 도구
LLM이 대신 코드를 짜주는 게 아니라, 직접 손으로 따라할 수 있는 실습형 튜토리얼을 생성해주는 CLI 도구다. AI에게 생각을 맡기는 대신 배움의 도구로 활용하는 접근법이라 주목받고 있다.
Meta AI 챗봇 악용으로 Instagram 계정 20,000개 이상 해킹 확인
Meta의 AI 챗봇에 있던 이메일 검증 버그로 인해 2FA(2단계 인증)를 사용하지 않던 Instagram 계정 2만 개 이상이 약 2개월간 해킹됐다. AI를 계정 복구 시스템에 통합할 때 발생할 수 있는 보안 취약점의 실제 사례다.
Anthropic의 오픈소스 AI 기반 취약점 자동 탐지 프레임워크 공개
Anthropic이 Claude를 활용해 코드 취약점을 자율적으로 탐지·트리아지·패치하는 오픈소스 레퍼런스 구현체를 공개했다. 실제 보안팀과의 협업 경험을 바탕으로 만들어진 파이프라인이라 실전 적용성이 높다.
에이전트는 스스로 물러날까? LLM 에이전트의 In-Band Access-Deny 신호 준수 측정
서버가 SSH 배너나 DB NOTICE로 'AI 에이전트는 접근하지 마세요' 신호를 보내면 GPT-4o, Claude Code 같은 LLM 에이전트가 실제로 물러나는지 실험으로 측정했다.
ToolChoiceConfusion: 신뢰할 수 있는 LLM 에이전트를 위한 Causal Minimal Tool Filtering
LLM 에이전트에 도구를 100개 다 보여주지 말고, 지금 당장 필요한 것 1개만 보여주면 성공률은 그대로에 토큰은 90% 절약된다.
AI Agent를 위한 TDD(테스트 주도 개발) Skill 만들기
AI 에이전트가 형편없는 테스트를 작성하는 문제를 해결하기 위해, Kent Beck의 Canon TDD 원칙을 'Skill'로 만들어 에이전트에게 주입하는 방법을 공유한다. 에이전트 코딩에서 테스트 품질을 높이고 싶은 개발자에게 실용적인 접근법을 제시한다.