Bitwarden CLI, Checkmarx 공급망 공격 캠페인에 감염
Bitwarden CLI compromised in ongoing Checkmarx supply chain campaign
TL;DR Highlight
Bitwarden CLI npm 2026.4.0이 CI/CD GitHub Action 악용으로 악성 코드에 감염됐다
Who Should Read
npm 패키지를 CI와 로컬에서 자동 설치하고 Claude/MCP 설정과 클라우드 자격증명을 쓰는 백엔드·DevOps 개발자
Core Mechanics
- 감염된 건 @bitwarden/cli 2026.4.0
- 악성 코드는 패키지에 포함된 bw1.js 파일에 있었다.
- Bitwarden CI/CD 파이프라인의 GitHub Action이 악용된 것으로 보인다고 Socket은 밝혔다.
- npm 패키지만 영향을 받았고 Chrome 확장·MCP 서버 등 다른 배포본은 아직 영향이 없다.
- 훔쳐 가는 자격증명 범위가 넓다
- GitHub 토큰, AWS/Azure/GCP 자격증명, .npmrc, SSH 키, 환경변수를 수집한다.
- Claude/MCP 설정 파일도 수집 대상에 들어 있다.
- GitHub 토큰은 Runner.Worker 메모리 스크래핑으로도 빼낸다.
- 유출은 GitHub 공개 저장소로 이뤄진다
- 피해자 계정에 {word}-{word}-{3digits} 형태의 Dune 테마 이름으로 공개 저장소를 만든다.
- 암호화한 결과를 커밋하고 토큰은 LongLiveTheResistanceAgainstMachines 표식과 함께 커밋 메시지에 넣는다.
- C2는 audit.checkmarx[.]cx/v1/telemetry를 쓴다.
- 다른 패키지로 번지는 구조
- 훔친 npm 토큰으로 쓰기 가능한 패키지를 찾아 preinstall 훅을 심어 재배포한다.
- GitHub Actions 워크플로를 주입해 저장소 시크릿도 캡처한다.
- 셸 프로필에 심어 지속성 확보
- ~/.bashrc와 ~/.zshrc에 페이로드를 주입한다.
- /tmp/tmp.987654321.lock으로 중복 실행을 막는다.
- 시스템 로케일이 ru로 시작하면 조용히 종료한다.
- 어제 분석한 Checkmarx 공격과 같은 도구 기반
- C2 엔드포인트와 난독화 방식이 Checkmarx mcpAddon.js와 같다.
- 이번 페이로드엔 Shai-Hulud: The Third Coming 같은 이념적 브랜딩이 직접 들어 있다.
- Socket은 같은 운영자인지는 단정하지 못하고 귀속이 복잡하다고 썼다.
Community Reactions
- min-release-age로 막을 수 있었다는 의견
- 댓글에서 .npmrc의 min-release-age=7(npm 11.10+)을 쓰면 악성 버전을 받은 334명이 피해를 피했을 거라는 의견이 나왔다.
- pnpm, bun, uv에도 같은 기능이 있다는 설정 예시가 공유됐다.
- axios, ua-parser-js 악성 버전은 몇 시간 만에 내려갔지만 event-stream은 2개월 넘게 남아 있었다는 언급도 있다.
- preinstall이면 설치만으로 끝이라는 지적
- 댓글에서 설치 후 검사는 이미 늦고 에이전트·CI·임시 샌드박스는 자동 반복 설치라 짧은 노출도 충분하다는 의견이 나왔다.
- 셸 프로필 변조가 다음 코딩 어시스턴트의 컨텍스트를 오염시킬 수 있다는 우려도 있었다.
- 의존성 고정과 Actions 핀닝 경험담
- 댓글에서 ^ 범위는 락파일이 갱신될 때 새 버전을 끌어올 수 있으니 핵심 서비스는 버전을 고정하라는 의견이 나왔다.
- GitHub 공식 checkout 액션도 못 믿어 직접 체크아웃으로 바꿨다는 경험이 공유됐다.
- 해시 고정은 원천에서 오염된 업로드는 못 막는다는 반론도 있었다.
- 대안 도구 추천
- 댓글에서 Rust로 만든 rbw, 그리고 pass/gopass에 비공개 git 저장소 동기화를 쓰는 방식이 대안으로 언급됐다.
- Raycast 번들 bitwarden-cli는 감염 버전이 아니라는 확인 댓글도 있었다.
How to Apply
- npm 설정에 최소 릴리스 경과일 걸기
- 오늘 ~/.npmrc에 min-release-age=7을 추가하라(npm 11.10 이상).
- pnpm은 minimum-release-age=10080(분), bun은 minimumReleaseAge=604800(초), uv는 exclude-newer="7 days"를 설정하라.
- 설치 이력과 감염 흔적 점검하기
- @bitwarden/cli 2026.4.0을 설치한 개발 머신과 CI 러너를 찾아라.
- /tmp/tmp.987654321.lock 파일과 ~/.bashrc, ~/.zshrc 변조 여부를 확인하라.
- audit.checkmarx[.]cx 및 94[.]154[.]172[.]43 대상 아웃바운드 연결을 로그에서 검색하라.
- 노출 가능 시크릿 전부 교체하기
- 감염 버전이 실행된 환경의 GitHub·npm 토큰, 클라우드 자격증명, SSH 키, CI 시크릿을 회전하라.
- GitHub 계정에서 Dune 용어 이름의 신규 공개 저장소와 .github/workflows/ 아래 미승인 워크플로를 확인하라.
- GitHub Actions 권한과 토큰 범위 줄이기
- 워크플로 permissions를 최소로 제한하고 서드파티 액션은 커밋 해시로 고정하라.
- 가능하면 단기 자격증명을 쓰고 npm 패키지 발행 권한자를 제한하라.
Try It
# 셸(터미널)에 그대로 붙여넣기: 감염 흔적 간이 점검 (macOS/Linux)
npm ls -g @bitwarden/cli 2>/dev/null | grep 2026.4.0 && echo "[!] 감염 버전 설치됨"
find . -path '*/node_modules/@bitwarden/cli/package.json' -exec grep -H '"version"' {} \; 2>/dev/null
[ -f /tmp/tmp.987654321.lock ] && echo "[!] lock 파일 발견"
grep -nE 'bw1\.js|checkmarx\.cx' ~/.bashrc ~/.zshrc 2>/dev/null
ls -d /tmp/_tmp_* 2>/dev/null
# npm 최소 릴리스 경과일 설정 (npm 11.10+)
npm config set min-release-age 7Terminology
관련 논문
WhatsApp 도움말 페이지에 숨겨진 LLM 지시문: 규제기관을 추천하지 말라
WhatsApp 도움말에 화면엔 안 보이는 AI 지시문 102개가 숨어 있었다
같은 시뮬레이션, 다른 근거: 도구 출력을 파일로 넘기면 LLM 에이전트 정확도가 어디서 깎이나
긴 툴 출력을 파일로 넘기자 GPT-5.1은 정확도 11.3%p 하락, 정식 출력 지정하니 회복
가짜 뉴스가 진짜 폭락을: LLM 트레이딩 에이전트 대상 정보 주입 공격
가짜 헤드라인 한 줄로 LLM 트레이딩 에이전트 62%를 조종했다(프롬프트 주입은 14%)
Harness Engineering 101: LLM은 뇌, harness는 몸
에이전트는 JSON 배열을 관리하는 루프이고, 16개 챕터로 직접 만들어 본다
Harness²: 에이전트 harness를 스스로 고쳐 쓰는 재귀 최적화 프레임워크
모델은 고정하고 harness를 재귀로 고쳤더니 벤치마크 점수가 최대 11.8%p 올랐다
Ask HN: 이해 못 하는 AI 작성 코드를 배포할 때 어떻게 하나
설계는 내가, 구현은 LLM이: 이해 못 하는 코드를 다루는 개발자들의 방법
해고된 Savannah 경찰관, ICE 요원 남편에게 Flock 계정 공유
경찰관이 Flock 계정을 남편(ICE 요원)에게 공유했고, 감사에서 983건 검색이 드러나 해고됐다
tmux와 Claude Code: 세션, send-keys, 그리고 한계선
tmux로 Claude Code 여러 개를 돌리면 편하지만 에이전트 4개쯤에서 한계가 온다