한 달 전쯤 귀찮은 작업을 해야 해서 NPM 패키지를 찾았음 brew install npm을 실행하자 의존성 폭포가 쏟아졌고, 잠시 멈춰 리스크와 이득을 생각하다가 결국 brew uninstall npm으로 되돌림
대신 오래된 Unix 유틸리티 파이프라인과 awk로 해결했는데, 지금 생각해보면 최고의 결정이었음
교훈은 명확함 — 웹 기술을 로컬 스크립팅에 쓰지 말아야 함
NPM은 브라우저 호환성 문제를 해결하려 만든 도구라, 브라우저가 없는 환경에서 불필요한 복잡성을 초래함
이런 이유로 컨테이너화나 가상화가 필요함
Node나 Python처럼 의존성이 많은 생태계의 코드를 메인 시스템에서 직접 실행하면 공급망 공격에 노출될 위험이 큼
그래서 나는 아예 Python이나 JS 인터프리터를 기본 시스템에 설치하지 않음
나도 예전엔 npm을 Docker 컨테이너 안에서만 돌렸는데, 포럼에서 종종 비웃음을 샀음
결국 포기했지만 지금은 그게 맞았던 것 같음
나도 비슷한 경험이 있음. artillery가 끌어오려는 의존성 수를 보고 바로 포기했음
아이러니하게도, 개발자들은 늘 “상식이 최고의 보안”이라 말하면서도 검증되지 않은 수많은 패키지를 한 줄 명령으로 설치함
“GitHub이 악성 저장소를 대량 삭제하면 수천 개 시스템이 동시에 사용자 데이터를 파괴할 수 있다”는 말이 있었는데,
마치 인질극 같음 — 그래서 “인질을 쏴라” 는 농담이 나옴
하지만 인질(사용자)이 스스로 위험에 들어간 셈이라, 결국 자기 선택의 결과임
나도 이번 npm 공격의 피해자임
GitHub CLI가 HOME 디렉토리에 평문 OAuth 토큰을 저장한다는 걸 알고 충격받았음
공격자가 접근하면 내 계정으로 거의 모든 행동이 가능했음
사실 GitHub CLI는 keyring이 없을 때만 토큰을 평문으로 저장함
macOS에서는 OS 키체인에 안전하게 저장됨 — 관련 토론
맞음, 하지만 브라우저 쿠키 파일도 비슷한 문제를 가짐
Chrome은 OS 보호 기능을 쓰지만 Firefox는 아직 아님
결국 sandbox 기반 접근 제어가 근본적인 해결책임
모든 토큰은 보호된 키체인에 있어야 함
하지만 플랫폼 간 일관된 솔루션이 없고, MacOS에서도 완벽한 방법이 없음
나도 피해자임. Backstage 설치 후 감염됨 ~/.dev-env 디렉토리가 생기며 내 노트북이 GitHub runner로 변했음
Bluefin Linux의 읽기 전용 파일 시스템 덕분에 피해가 줄었을지도 모름
모두 npm만 탓하지만, GitHub의 책임도 큼
악성 저장소를 빠르게 탐지하지 못했고, 이미 악성코드 저장소 문제가 심각함
그래도 GitHub에 업로드된 덕분에 피해를 빨리 알아챈 사람도 있었음
만약 몰래 외부 서버로 전송됐다면 더 끔찍했을 것임
Microsoft가 모든 걸 필터링해줄 순 없음 커뮤니티 차원의 도구와 관행이 필요함
GitHub이 Microsoft 소유라 GoLang 패키지 저장소와도 얽혀 있음
상업적 규제나 빌드 워크플로 제한이 생기면 큰 문제로 이어질 수 있음
두 회사 모두 보안 수준이 평범하다는 점은 부정할 수 없음
이 악성코드는 동일한 패턴으로 저장소를 생성하므로, 간단한 규칙으로도 탐지 가능했을 것임
왜 NPM만 공격 대상이 되는지 궁금했음
Python이나 Java도 인기 많은데, 최근엔 조용함
NPM은 post-install hook으로 임의 명령 실행이 가능하고, 버전 범위 의존성 문화 덕분에 감염이 빠르게 확산됨
Java는 특정 버전 고정이 일반적이라 이런 일이 드묾
Node는 표준 라이브러리가 작고 커뮤니티 의존도가 높음
그래서 하나의 패키지가 수십 개의 하위 의존성을 끌어옴
JS는 GitHub에서 가장 인기 있는 언어라 공격 표면이 넓고
경험이 적은 개발자들이 많아 보안이 약함
JS 커뮤니티는 “최신 버전 강박증”이 심함
다른 언어 생태계는 검증 후 업데이트하지만 JS는 즉시 업그레이드함
NPM은 보안 경계가 약함
설치 시 스크립트를 자유롭게 실행할 수 있었고, JVM이나 Python은 그렇지 않음
Hacker News 의견
한 달 전쯤 귀찮은 작업을 해야 해서 NPM 패키지를 찾았음
brew install npm을 실행하자 의존성 폭포가 쏟아졌고, 잠시 멈춰 리스크와 이득을 생각하다가 결국brew uninstall npm으로 되돌림대신 오래된 Unix 유틸리티 파이프라인과 awk로 해결했는데, 지금 생각해보면 최고의 결정이었음
NPM은 브라우저 호환성 문제를 해결하려 만든 도구라, 브라우저가 없는 환경에서 불필요한 복잡성을 초래함
Node나 Python처럼 의존성이 많은 생태계의 코드를 메인 시스템에서 직접 실행하면 공급망 공격에 노출될 위험이 큼
그래서 나는 아예 Python이나 JS 인터프리터를 기본 시스템에 설치하지 않음
결국 포기했지만 지금은 그게 맞았던 것 같음
“GitHub이 악성 저장소를 대량 삭제하면 수천 개 시스템이 동시에 사용자 데이터를 파괴할 수 있다”는 말이 있었는데,
마치 인질극 같음 — 그래서 “인질을 쏴라” 는 농담이 나옴
나도 이번 npm 공격의 피해자임
GitHub CLI가 HOME 디렉토리에 평문 OAuth 토큰을 저장한다는 걸 알고 충격받았음
공격자가 접근하면 내 계정으로 거의 모든 행동이 가능했음
macOS에서는 OS 키체인에 안전하게 저장됨 — 관련 토론
Chrome은 OS 보호 기능을 쓰지만 Firefox는 아직 아님
결국 sandbox 기반 접근 제어가 근본적인 해결책임
하지만 플랫폼 간 일관된 솔루션이 없고, MacOS에서도 완벽한 방법이 없음
~/.dev-env디렉토리가 생기며 내 노트북이 GitHub runner로 변했음Bluefin Linux의 읽기 전용 파일 시스템 덕분에 피해가 줄었을지도 모름
모두 npm만 탓하지만, GitHub의 책임도 큼
악성 저장소를 빠르게 탐지하지 못했고, 이미 악성코드 저장소 문제가 심각함
만약 몰래 외부 서버로 전송됐다면 더 끔찍했을 것임
커뮤니티 차원의 도구와 관행이 필요함
상업적 규제나 빌드 워크플로 제한이 생기면 큰 문제로 이어질 수 있음
왜 NPM만 공격 대상이 되는지 궁금했음
Python이나 Java도 인기 많은데, 최근엔 조용함
버전 범위 의존성 문화 덕분에 감염이 빠르게 확산됨
Java는 특정 버전 고정이 일반적이라 이런 일이 드묾
그래서 하나의 패키지가 수십 개의 하위 의존성을 끌어옴
경험이 적은 개발자들이 많아 보안이 약함
다른 언어 생태계는 검증 후 업데이트하지만 JS는 즉시 업그레이드함
설치 시 스크립트를 자유롭게 실행할 수 있었고, JVM이나 Python은 그렇지 않음
.npmrc에를 추가하면 공격 벡터를 줄일 수 있음
관련 글
비활성화 시 의존성 깨짐 위험은 없는지도 의문임
이번 공격에서 가장 걱정되는 건 자격 증명 탈취임
감염된 패키지를 설치했다면 환경 변수나
.npmrc토큰이 유출됐을 수 있음즉시 토큰과 API 키를 회전해야 함
주기적 회전은 침해 후 대응이 아니라 사전 예방책임
자격 증명은 환경 변수나 파일에 저장하지 말고 보안 키나 암호화 파일을 써야 함
마치 분산 원장에 악성 트랜잭션을 심는 것 같음
여전히 많은 서비스가 평문 저장을 기본값으로 두는 게 문제임
이런 공격이 반복되는데, 왜 AI 기반 탐지 시스템이 작동하지 않는지 의문임
Microsoft가 AI를 그렇게 강조하는데, 정작 GitHub 보안엔 안 쓰이는 듯함
방화벽이 막은 모든 시도를 공격으로 분류하던 시절처럼 의미가 퇴색됨
내부적으로 SonaType IQ Server가 이를 지원함
실제로 curl 프로젝트가 AI 생성 보안 리포트 스팸에 시달린 사례도 있음
postinstall 스크립트를 계속 허용할 이유가 있는지 궁금함
사용자에게 실행 여부를 묻는 게 낫지 않을까 생각함
CI 서버에서는 비대화식 설치가 필요하므로 현실적으로 어렵다고 봄
글이 매우 통찰력 있었는데, 마지막에 GitLab 보안 기능 홍보로 끝나서 아쉬웠음