Hacker News 의견
  • 한 달 전쯤 귀찮은 작업을 해야 해서 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은 그렇지 않음
  • .npmrc

    ignore-scripts=true
    

    를 추가하면 공격 벡터를 줄일 수 있음
    관련 글

    • 설치 전에 preinstall/postinstall hook이 있는 패키지를 미리 확인할 방법이 있는지 궁금함
    • “ignore scripts”가 안전하다면 왜 존재하는 옵션인지,
      비활성화 시 의존성 깨짐 위험은 없는지도 의문임
    • 하지만 결국 Node 환경에서 JS를 실행하면 환경 변수나 파일 접근은 막을 수 없음
    • 혹은 그냥 pnpm을 쓰는 것도 방법임
  • 이번 공격에서 가장 걱정되는 건 자격 증명 탈취
    감염된 패키지를 설치했다면 환경 변수나 .npmrc 토큰이 유출됐을 수 있음
    즉시 토큰과 API 키를 회전해야 함
    주기적 회전은 침해 후 대응이 아니라 사전 예방책

    • 개발자가 비밀번호 재사용을 한다면 정말 심각한 문제임
      자격 증명은 환경 변수나 파일에 저장하지 말고 보안 키나 암호화 파일을 써야 함
    • 감염 여부를 모른다면 먼저 감염 탐지 → 정리 → 토큰 회전 순으로 해야 함
    • 이번 공격은 단순한 감염이 아니라 생태계 전체를 인질로 잡는 형태라 더 위험함
      마치 분산 원장에 악성 트랜잭션을 심는 것 같음
    • 비밀은 반드시 보안 저장소(secret locker) 에 보관해야 함
      여전히 많은 서비스가 평문 저장을 기본값으로 두는 게 문제임
    • 그리고 이 악성코드는 전파가 멈추면 데이터 파괴까지 시도함
  • 이런 공격이 반복되는데, 왜 AI 기반 탐지 시스템이 작동하지 않는지 의문임
    Microsoft가 AI를 그렇게 강조하는데, 정작 GitHub 보안엔 안 쓰이는 듯함

    • 하지만 “AI가 공격을 탐지했다”는 말은 이미 보안 마케팅의 상투어가 됨
      방화벽이 막은 모든 시도를 공격으로 분류하던 시절처럼 의미가 퇴색됨
    • 우리 회사는 SonaType Lifecycle을 쓰는데, AI 기반으로 이런 공격을 막는다고 함
      내부적으로 SonaType IQ Server가 이를 지원함
    • 현재의 “AI”는 생성형 모델이라 평가보다는 생성에 초점이 맞춰져 있음
      실제로 curl 프로젝트가 AI 생성 보안 리포트 스팸에 시달린 사례도 있음
  • postinstall 스크립트를 계속 허용할 이유가 있는지 궁금함
    사용자에게 실행 여부를 묻는 게 낫지 않을까 생각함

    • 하지만 대부분의 사용자는 “예”를 누를 것이고,
      CI 서버에서는 비대화식 설치가 필요하므로 현실적으로 어렵다고 봄
  • 글이 매우 통찰력 있었는데, 마지막에 GitLab 보안 기능 홍보로 끝나서 아쉬웠음

    • GitLab 사용자라면 유용했을 수도 있음
    • 그래도 그게 글의 통찰력 자체를 깎지는 않음