최소 릴리스 대기 기간을 두는 것보다 더 나은 방어책이 있는지 궁금함 .npmrc에 min-release-age=7만 넣었어도, 약 19시간 전 올라왔다가 악성으로 드러난 @bitwarden/cli 2026.4.0을 받은 334명은 피할 수 있었을 것 같음
비슷하게 axios, ua-parser-js, node-ipc 사례에도 꽤 잘 맞고, event-stream처럼 오래 잠복한 경우엔 못 막아도 대부분의 급성 공급망 공격엔 효과가 있어 보임
설정 예시로 npm/pnpm/bun/uv 각각에 대기 시간을 넣는 방법이 있고, 원클릭으로 점검·적용하는 도구가 없어서 직접 https://depsguard.com을 만들었음
비슷한 아이디어의 https://cooldowns.dev도 방금 확인함
Aikido safe-chain을 쓰고 있음
최소 릴리스 대기 기간만 거는 게 아니라, npm/uv 등을 감싸는 래퍼로 설치 전에 각 의존성을 상용 취약점 데이터베이스와 대조해 알려진 문제나 의심 신호를 검사해 줌
쿨다운 아이디어는 좋은데, 아무도 바로 업데이트하지 않았다면 이 공격이 과연 잡혔을지도 궁금함
현실에선 늘 누군가는 즉시 업데이트하겠지만, 이런 사고가 드러나는 과정 자체가 빠른 업데이트 사용자들에 기대는 면이 있어 보임
backend나 CLI 도구를 NPM에 두지 않는 것부터 시작하는 편이 낫다고 봄
새로 설치할 때는 그렇다 쳐도, 기존 의존성은 patch 버전으로 pin하고 sha를 고정하면 되지 않나 싶음
이런 공격은 대개 upstream source까지 들어가지 않아서, https://www.chainguard.dev/libraries처럼 소스에서 빌드하는 방식이면 대략 98%는 막을 수 있음
레지스트리 바이너리를 그대로 당겨와야 한다면 쿨다운으로 위험을 조금 낮출 수 있음
GitHub 쪽까지 침투한 긴 꼬리 사례는 커밋·메인테이너 휴리스틱과 AI 기반 코드 변경 분석을 돌리고, 이상 징후가 있으면 사람이 검토하는 조합이 필요해 보임
참고로 여기서 일하고 있음
이번 사고는 빌드 파이프라인이 탈취돼서 오염된 패키지가 배포된 게 핵심임
그래도 업무상 중요한 걸 npm에 얹고 있다면 의존성은 꼭 pinning하는 편이 낫다고 봄
많은 개발자가 lockfile이면 충분하다고 여기지만, ^ 범위가 남아 있으면 lockfile 갱신 시 내가 명시적으로 고르지 않은 새 버전을 끌어올 수 있음
회사 존립에 영향 줄 수 있는 시스템이라면 이 정도 번거로움은 감수할 가치가 있음
반대로 생각하면, 나중 버전에서 보안 취약점이 수정됐을 때는 시스템이 그걸 자동으로 받아 적용해 주는 게 이상적이기도 함
https://github.com/doy/rbw는 Bitwarden CLI의 Rust 대안임
Rust 생태계도 점점 npm처럼 크고 깊은 의존성 트리로 가는 느낌이 있지만, 그래도 JavaScript에서 흔한 경우보다 신뢰해야 할 작성자 수는 훨씬 적은 편임
다들 Rust를 더 안전하다고 보면서도, 의존성을 통해 멀웨어를 끌어올 위험이 크게 늘어난 건 너무 쉽게 무시하는 듯함
rbw + vaultwarden 조합이면 self-hostable Rust 버전의 Bitwarden처럼 굴러가서 꽤 괜찮음
이런 일 때문에 더 많은 소프트웨어가 .Net처럼 서드파티 의존성 없이도 대부분 해결되는 스택으로 갈 수도 있겠다고 봄
반대로 언어 표준 라이브러리에 기능을 더 많이 넣는 쪽으로 갈 수도 있음
Bitwarden CLI 경험이 아주 나빴음 bw list를 실행했더니 비밀번호 이름만 나올 줄 알았는데, 실제로는 비밀번호와 현재 TOTP 코드까지 전부 보여줬음
더 무서운 건 서버에 ssh로 들어가 tmux 안의 weechat를 열어 보니, bw 명령의 전체 내용이 weechat 입력 히스토리에서 접근 가능했다는 것임
왜 그런지 전혀 모르겠고, tmux와 weechat 세션을 넘어 계속 남아 있었고 서버를 재부팅해야만 사라졌음
그 뒤로 bw CLI는 바로 지웠고 다시 설치할 생각도 없음
참고로 터미널은 ghostty를 씀
이건 본 주제와 상관없는 불평에 가까움
CLI를 써보려다가 JavaScript 기반인 걸 보고 접었음
정말 이상한 일임
weechat에 bwcli 확장이라도 있는 건지 궁금하고, Bitwarden에 CLI가 있는지도 이번에 처음 알았음
나는 로컬에서 keepass를 씀
CLI는 안 써봤지만 브라우저 플러그인은 쓰고 있음
이게 뚫리면 정말 큰일인데, 뭘 해야 막을 수 있을지 모르겠음
검증된 구버전을 계속 쓰는 게 답인지 고민됨
내 삶의 상당 부분이 이 비밀들이 비밀로 남는 데 달려 있다는 사실이 새삼 기묘하게 느껴짐
통합 지점이 많아질수록 공격면도 커짐
그래서 비밀번호 관리자 브라우저 확장은 아예 쓰지 않음
예전에 브라우저 연동에서 보안 문제가 있었던 제품을 본 뒤로 완전히 피하게 됐고, iOS 통합은 상대적으로 더 믿지만 그래도 경계함
쿨다운은 기본값으로 어디에나 들어가야 한다고 봄
개발용 패키지 매니저, OS 패키지 매니저, 브라우저 확장, 독립 앱의 자동 업데이트까지 전부 포함해서 말임
Socket 같은 회사가 악성 업데이트를 잡아낼 시간을 벌어야 하는데, 모두가 게시 몇 분 만에 내려받으면 그런 탐지 자체가 무의미해짐
내 디지털 자산 중 가장 소중한 이메일과 Bitwarden 계정은 항상 몸에 지니는 Yubikey 하나와 다른 지역에 둔 백업 키 하나로 보호하고 있음
이런 구성을 강력히 추천함
제목 보고 좀 식겁하긴 했지만, 편집증으로 갈 정도는 아니면서 합리적으로 할 수 있는 건 다 하고 있다고 느낌
여기서 가장 중요한 건 npm install만으로 충분했다는 사실임
침해 지점이 preinstall이면, 설치 후 검사하자는 통념은 바로 무너짐
그 시점엔 이미 페이로드가 실행될 기회를 얻었기 때문임
이건 에이전트, CI, ephemeral sandbox 환경에서 더 흥미로운데, 노출 시간이 짧아도 설치가 자동으로 반복되면 충분히 당할 수 있음
또 하나 주목할 건 이 페이로드가 비밀정보만 노린 게 아니라 AI 툴링 설정도 겨냥했다는 점임
셸 프로필 변조가 다음 코딩 어시스턴트가 읽어갈 컨텍스트를 오염시키는 경로가 될 가능성도 꽤 현실적임
이 관점은 AgentSH 작업과 함께 https://www.canyonroad.ai/blog/the-install-was-the-attack/에 더 길게 적어둠
설치 후 패키지를 검사하는 사람은 사실상 없고, npm install 스크립트만 특별히 문제 삼는 건 여러 번 반박된 주장이라고 봄
어차피 결국 실제 바이너리를 실행하게 됨
그리고 정말 따지자면 설치 전에 패키지를 직접 받아 검사할 수도 있는데, 설치 프로그램의 동작 보장과 범위를 깊이 이해하지 못한다면 악성 코드를 내려받고 풀어놓는 과정을 어설프게 신뢰하는 쪽이 더 이상함
러시아 로캘 kill switch라니, 대담하면서도 비겁해 보임
더 나쁜 건 이게 진짜 흔적인지, 아니면 false flag인지조차 알 수 없다는 점임
Discretion is the better part of valor 같은 온갖 격언이 다 떠오름
요컨대 자기 발등은 찍지 않는다는 태도처럼 보임
그 자체로 결정적 증거는 아님 Vault7 유출에서도 NSA와 CIA가 출처를 흐리려고 이런 흔적을 일부러 남긴다는 내용이 있었고, 다른 국가 행위자들도 충분히 쓸 법한 기법임
다른 나라가 건 협박성 공작처럼도 보임
npm publish GitHub CI 작업에서 누가 로캘을 그렇게 맞춰 두겠냐 싶음
너무 노골적인 오도용 흔적 같지만, 동시에 국가 행위자가 개입했다는 인상을 강하게 주긴 함
KeePass 사용자로 살면 이런 스트레스가 훨씬 적음
지난 5년만 해도 로컬 인프라에 KeePass를 써서 여러 보안 사고를 피했음
이번 건 vault 자체가 아니라 접근 도구가 문제였음
KeePass용 접근 도구라고 해서 이런 문제가 불가능한 건 아닌데, 무엇이 다르다는 건지 잘 모르겠음
비밀번호를 인프라와 휴대폰에서 함께 접근해야 하는데, KeePass로 그걸 어떻게 해결하는지 궁금함
불가능하다고 생각해 왔지만 솔직히 깊게 파보진 않았음
자기 인프라를 굴릴 수 있는 사람에겐 좋겠지만, stress free라는 표현을 평균 사용자에게까지 적용하긴 어려움
단일 파일 방식은 알겠는데, 현실적으로 동기화와 충돌 해결을 어떻게 하는지 궁금함
두 기기가 오프라인 상태에서 각각 비밀번호를 추가한 뒤 다시 온라인이 되면 어떻게 처리하나 싶음
KeePass에서 아직 감을 못 잡은 건 클라우드 백업임
백업을 암호화하면 그 암호는 어디에 저장하고, 또 클라우드 제공자 비밀번호는 어디에 저장해야 하나 싶음
이번 공격에서 특히 인상적인 건, 공격자들이 GitHub가 다운되지 않은 타이밍과 정확히 맞춰야 했다는 점임
그래서 나는 서드파티 비밀번호 관리자를 아예 쓰지 않음
보안, 업데이트, 백업 같은 걸 제대로 해줄 거라고 계속 믿어야 하기 때문임
직접 stateless 비밀번호 생성기를 만들었고, 덕분에 기기 간 데이터 백업이나 동기화가 아예 필요 없음
아주 길고 강한 마스터 비밀번호와 서비스명, 사용자명을 넣으면 적절한 파라미터의 scrypt 해시를 돌려 브루트포스를 사실상 불가능하게 만드는 방식임
중요한 계정엔 2FA도 함께 씀
Hacker News 의견들
최소 릴리스 대기 기간을 두는 것보다 더 나은 방어책이 있는지 궁금함
.npmrc에min-release-age=7만 넣었어도, 약 19시간 전 올라왔다가 악성으로 드러난@bitwarden/cli 2026.4.0을 받은 334명은 피할 수 있었을 것 같음비슷하게
axios,ua-parser-js,node-ipc사례에도 꽤 잘 맞고,event-stream처럼 오래 잠복한 경우엔 못 막아도 대부분의 급성 공급망 공격엔 효과가 있어 보임설정 예시로 npm/pnpm/bun/uv 각각에 대기 시간을 넣는 방법이 있고, 원클릭으로 점검·적용하는 도구가 없어서 직접 https://depsguard.com을 만들었음
비슷한 아이디어의 https://cooldowns.dev도 방금 확인함
최소 릴리스 대기 기간만 거는 게 아니라, npm/uv 등을 감싸는 래퍼로 설치 전에 각 의존성을 상용 취약점 데이터베이스와 대조해 알려진 문제나 의심 신호를 검사해 줌
현실에선 늘 누군가는 즉시 업데이트하겠지만, 이런 사고가 드러나는 과정 자체가 빠른 업데이트 사용자들에 기대는 면이 있어 보임
레지스트리 바이너리를 그대로 당겨와야 한다면 쿨다운으로 위험을 조금 낮출 수 있음
GitHub 쪽까지 침투한 긴 꼬리 사례는 커밋·메인테이너 휴리스틱과 AI 기반 코드 변경 분석을 돌리고, 이상 징후가 있으면 사람이 검토하는 조합이 필요해 보임
참고로 여기서 일하고 있음
이번 사고는 빌드 파이프라인이 탈취돼서 오염된 패키지가 배포된 게 핵심임
그래도 업무상 중요한 걸 npm에 얹고 있다면 의존성은 꼭 pinning하는 편이 낫다고 봄
많은 개발자가 lockfile이면 충분하다고 여기지만,
^범위가 남아 있으면 lockfile 갱신 시 내가 명시적으로 고르지 않은 새 버전을 끌어올 수 있음회사 존립에 영향 줄 수 있는 시스템이라면 이 정도 번거로움은 감수할 가치가 있음
https://github.com/doy/rbw는 Bitwarden CLI의 Rust 대안임
Rust 생태계도 점점 npm처럼 크고 깊은 의존성 트리로 가는 느낌이 있지만, 그래도 JavaScript에서 흔한 경우보다 신뢰해야 할 작성자 수는 훨씬 적은 편임
그래도 적어도 버전은 pin되어 있음
rbw + vaultwarden조합이면 self-hostable Rust 버전의 Bitwarden처럼 굴러가서 꽤 괜찮음반대로 언어 표준 라이브러리에 기능을 더 많이 넣는 쪽으로 갈 수도 있음
Bitwarden CLI 경험이 아주 나빴음
bw list를 실행했더니 비밀번호 이름만 나올 줄 알았는데, 실제로는 비밀번호와 현재 TOTP 코드까지 전부 보여줬음더 무서운 건 서버에 ssh로 들어가 tmux 안의 weechat를 열어 보니,
bw명령의 전체 내용이 weechat 입력 히스토리에서 접근 가능했다는 것임왜 그런지 전혀 모르겠고, tmux와 weechat 세션을 넘어 계속 남아 있었고 서버를 재부팅해야만 사라졌음
그 뒤로
bwCLI는 바로 지웠고 다시 설치할 생각도 없음참고로 터미널은 ghostty를 씀
weechat에
bwcli확장이라도 있는 건지 궁금하고, Bitwarden에 CLI가 있는지도 이번에 처음 알았음나는 로컬에서 keepass를 씀
CLI는 안 써봤지만 브라우저 플러그인은 쓰고 있음
이게 뚫리면 정말 큰일인데, 뭘 해야 막을 수 있을지 모르겠음
검증된 구버전을 계속 쓰는 게 답인지 고민됨
내 삶의 상당 부분이 이 비밀들이 비밀로 남는 데 달려 있다는 사실이 새삼 기묘하게 느껴짐
그래서 비밀번호 관리자 브라우저 확장은 아예 쓰지 않음
예전에 브라우저 연동에서 보안 문제가 있었던 제품을 본 뒤로 완전히 피하게 됐고, iOS 통합은 상대적으로 더 믿지만 그래도 경계함
개발용 패키지 매니저, OS 패키지 매니저, 브라우저 확장, 독립 앱의 자동 업데이트까지 전부 포함해서 말임
Socket 같은 회사가 악성 업데이트를 잡아낼 시간을 벌어야 하는데, 모두가 게시 몇 분 만에 내려받으면 그런 탐지 자체가 무의미해짐
이런 구성을 강력히 추천함
제목 보고 좀 식겁하긴 했지만, 편집증으로 갈 정도는 아니면서 합리적으로 할 수 있는 건 다 하고 있다고 느낌
https://cooldowns.dev
https://depsguard.com
두 번째 건 내가 관리하고 있고, 첫 번째를 미리 알았으면 굳이 만들지 않았을 듯함
둘 다 거의 같은 일을 하고, 내 쪽은 Rust를 써서 약간 과한 편임
여기서 가장 중요한 건 npm install만으로 충분했다는 사실임
침해 지점이
preinstall이면, 설치 후 검사하자는 통념은 바로 무너짐그 시점엔 이미 페이로드가 실행될 기회를 얻었기 때문임
이건 에이전트, CI, ephemeral sandbox 환경에서 더 흥미로운데, 노출 시간이 짧아도 설치가 자동으로 반복되면 충분히 당할 수 있음
또 하나 주목할 건 이 페이로드가 비밀정보만 노린 게 아니라 AI 툴링 설정도 겨냥했다는 점임
셸 프로필 변조가 다음 코딩 어시스턴트가 읽어갈 컨텍스트를 오염시키는 경로가 될 가능성도 꽤 현실적임
이 관점은 AgentSH 작업과 함께 https://www.canyonroad.ai/blog/the-install-was-the-attack/에 더 길게 적어둠
어차피 결국 실제 바이너리를 실행하게 됨
그리고 정말 따지자면 설치 전에 패키지를 직접 받아 검사할 수도 있는데, 설치 프로그램의 동작 보장과 범위를 깊이 이해하지 못한다면 악성 코드를 내려받고 풀어놓는 과정을 어설프게 신뢰하는 쪽이 더 이상함
러시아 로캘 kill switch라니, 대담하면서도 비겁해 보임
Discretion is the better part of valor같은 온갖 격언이 다 떠오름요컨대 자기 발등은 찍지 않는다는 태도처럼 보임
Vault7유출에서도 NSA와 CIA가 출처를 흐리려고 이런 흔적을 일부러 남긴다는 내용이 있었고, 다른 국가 행위자들도 충분히 쓸 법한 기법임너무 노골적인 오도용 흔적 같지만, 동시에 국가 행위자가 개입했다는 인상을 강하게 주긴 함
KeePass 사용자로 살면 이런 스트레스가 훨씬 적음
지난 5년만 해도 로컬 인프라에 KeePass를 써서 여러 보안 사고를 피했음
KeePass용 접근 도구라고 해서 이런 문제가 불가능한 건 아닌데, 무엇이 다르다는 건지 잘 모르겠음
불가능하다고 생각해 왔지만 솔직히 깊게 파보진 않았음
두 기기가 오프라인 상태에서 각각 비밀번호를 추가한 뒤 다시 온라인이 되면 어떻게 처리하나 싶음
백업을 암호화하면 그 암호는 어디에 저장하고, 또 클라우드 제공자 비밀번호는 어디에 저장해야 하나 싶음
이번 공격에서 특히 인상적인 건, 공격자들이 GitHub가 다운되지 않은 타이밍과 정확히 맞춰야 했다는 점임
https://mrshu.github.io/github-statuses/
그래서 나는 서드파티 비밀번호 관리자를 아예 쓰지 않음
보안, 업데이트, 백업 같은 걸 제대로 해줄 거라고 계속 믿어야 하기 때문임
직접 stateless 비밀번호 생성기를 만들었고, 덕분에 기기 간 데이터 백업이나 동기화가 아예 필요 없음
아주 길고 강한 마스터 비밀번호와 서비스명, 사용자명을 넣으면 적절한 파라미터의 scrypt 해시를 돌려 브루트포스를 사실상 불가능하게 만드는 방식임
중요한 계정엔 2FA도 함께 씀