# Red Hat Cloud Services 전반에서 악성 npm 패키지 발견

> Clean Markdown view of GeekNews topic #30095. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=30095](https://news.hada.io/topic?id=30095)
- GeekNews Markdown: [https://news.hada.io/topic/30095.md](https://news.hada.io/topic/30095.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-06-02T09:51:38+09:00
- Updated: 2026-06-02T09:51:38+09:00
- Original source: [github.com/RedHatInsights](https://github.com/RedHatInsights/javascript-clients/issues/492)
- Points: 1
- Comments: 1

## Topic Body

- 이슈는 **열린 상태**이며, 본문 기준으로 담당자·마일스톤·연결된 브랜치나 PR은 없음
- `@redhat-cloud-services/` 범위의 여러 **npm 릴리스**에서 악성 버전이 발견됐다는 보안 이슈로 등록됨
- 참고 자료로 StepSecurity의 [분석 글](https://www.stepsecurity.io/blog/multiple-redhat-cloud-services-npm-packages-compromised)과 [OSS Security Feed 검색 결과](https://app.stepsecurity.io/oss-security-feed?q=@redhat-cloud-services)가 제시됨
- 업데이트된 영향 목록에는 `@redhat-cloud-services/chrome`, `frontend-components`, `rbac-client`, `types`, `vulnerabilities-client` 등 **32개 패키지**가 포함됨
- 표에 나온 손상 버전은 대부분 패키지당 3개이며, `@redhat-cloud-services/vulnerabilities-client`는 `2.1.9`, `2.1.11` 두 버전만 포함됨
- 전체 표 기준으로 손상된 버전은 **95개**로 집계 가능하며, 별도 언급된 외부 PR 제목도 `95 versions`를 가리킴
- `@redhat-cloud-services/frontend-components-*` 계열과 여러 `*-client` 패키지가 함께 포함돼, 단일 패키지가 아니라 같은 스코프 전반의 릴리스 문제가 됨
- 댓글에서는 “What are these?”라는 질문에 “all that module is pwned”라는 답변이 달려, 목록 전체가 침해됐다는 이해가 공유됨
- DanielRuf는 이 사건을 [supply-chain-incidents](https://codeberg.org/DanielRuf/supply-chain-incidents)에 추가했다고 남김
- GitHub 활동에는 이 이슈를 참조한 콘텐츠 요약과 탐지 관련 PR이 보이지만, 본문에는 Red Hat 측의 진단·완화 조치·삭제 여부·수정 버전이 아직 제시되지 않음

## Comments



### Comment 58783

- Author: neo
- Created: 2026-06-02T09:51:39+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48356625) 
- **쿨다운** 설정 얘기로 스레드를 다시 빌려도 괜찮길 바람. axios, tanstack, @redhat-cloud-services와 최근의 여러 npm 공급망 공격은 쿨다운이 있었으면 막을 수 있었을 것임  
  Artifactory/Nexus를 쓰면 이미 있을 가능성이 크고, 없더라도 설정은 쉬움. npm이나 PyPI 침해 대부분은 몇 시간 안에 내려갔으니, 릴리스된 지 N일 미만인 패키지를 무시하는 방식이면 충분함. 1일도 효과가 있고, 3일은 괜찮으며, 7일은 다소 과하지만 동작함  
  최신 pnpm은 기본으로 1일 쿨다운을 넣었음: [https://pnpm.io/supply-chain-security](<https://pnpm.io/supply-chain-security>)  
  한 번 클릭으로 끝내고 싶으면 [https://depsguard.com](<https://depsguard.com>)을 쓸 수 있음. npm, pnpm, yarn, bun, uv, dependabot에 쿨다운과 권장 설정을 추가하는 CLI이며, 내가 유지보수자임  
  쿨다운에 더 집중한 [https://cooldowns.dev](<https://cooldowns.dev>)도 있고, 로컬 설정을 돕는 스크립트도 있음. 모두 오픈소스/무료임  
  `~/.npmrc` 등을 직접 편집할 줄 알면 굳이 필요 없지만, 주변에 원클릭 수정만 필요한 사람이 있다면 다음 공격을 피하는 데 도움이 될 수 있음  
  단, 새 치명적 CVE를 패치해야 할 때는 쿨다운을 우회해야 하며, 각 도구에 우회 방법이 있음. 최근 몇 달은 정확한 수치는 없지만, Mythos식 취약점 발견 시대에도 새 제로데이 CVE보다 **악성 버전 배포** 같은 소프트웨어 공급망 공격 쪽 위험이 더 커 보임
  - 임베디드 개발자로서 툴체인과 의존성을 몇 년씩 고정하는 데 익숙하다 보니, **웹 개발 문화**는 여러 면에서 충격적임
  - sane하고 조금 더 안전한 설정 방법을 모아둔 친구의 GitHub 저장소가 있음: [https://github.com/jordanconway/package-manager-hardening](<https://github.com/jordanconway/package-manager-hardening>)
  - Docker/Podman 이미지 pull에도 **쿨다운**을 넣는 합리적인 방법이 있을까?
  - `~/.npmrc` 파일을 열고 한 줄 추가할 수 있는 사람인데도 원클릭 수정이 필요한 경우는 아주 작은 집단처럼 느껴짐
  - 쿨다운과 더불어 더 많은 패키지 관리자가 **보안 수정**과 일반 릴리스(버그 수정/성능 개선/새 기능)를 구분해 처리하면 좋겠음  
    “보안 수정은 보안 수정만 포함해야 하며 다른 기능을 실으면 안 된다”고 말하는 건 충분히 가능함. 그러면 보안 연구자와 도구 모두가 감사하기 쉬워짐  
    일반 릴리스에는 쿨다운을 적용하고, 보안 수정에는 쿨다운을 없애거나 훨씬 짧게 둘 수 있음  
    Debian처럼 매우 안정적인 서버를 두고, unattended upgrades를 보안 수정에만 적용하도록 설정할 수 있는 체계는 참고할 만함. 이런 새 패키지 릴리스는 보안 연구자가 감사하기도 더 쉬움

- 이런 스레드마다 이 공격 유형이 npm에만 있는 것처럼 굴거나, 아무 조치도 없었던 것처럼 비꼬는 댓글이 많지만, 그건 공정하지 않다고 봄  
  지연선(delay line)과 pnpm 등이 패키지 소비자를 보호하려고 도입한 좋은 기능들을 언급하는 댓글도 많음  
  덜 이야기되는 부분은 **패키지 유지보수자 쪽 도구**임. 배포용 MFA: [https://docs.npmjs.com/requiring-2fa-for-package-publishing-...](<https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification>), 약 1년 전부터 제공된 trusted publishers: [https://docs.npmjs.com/trusted-publishers](<https://docs.npmjs.com/trusted-publishers>)  
  최근에는 두 기능의 장점을 합친 **staged publishing**도 나왔음: [https://docs.npmjs.com/staged-publishing](<https://docs.npmjs.com/staged-publishing>)  
  이제 정적 자격 증명 없이 CI에서 배포하고, 레지스트리에 실제 공개되기 전 유지보자가 MFA로 승인하도록 요구할 수 있음. 원하면 GitHub Actions Environments 보호로 CI 쪽에서 다중 승인이나 시간 지연도 요구 가능함  
  커뮤니티가 이런 배포 보호 장치를 채택하도록 장려해야 하며, 그렇지 않으면 이 문제는 계속될 것임
  - [1]에 따르면 “영향받은 모든 패키지는 RedHatInsights/javascript-clients 저장소에서 GitHub Actions OIDC를 통해 배포됐고, 이는 상류 CI/CD 파이프라인 자체가 침해됐음을 나타낸다”고 함  
    그러면 악성 패키지도 초록색 별을 받고, 사용자에게 “출처 증명과 함께 빌드되고 서명됨”이라고 안심시켰을 것임  
    [1] [https://lwn.net/Articles/1075742/](<https://lwn.net/Articles/1075742/>)
  - 계속 벌어지고 있으니 웃기긴 함. npm 공격은 달력에 표시할 수 있을 정도고, 누군가 The Onion의 고전 “피할 방법이 없다” 기사 패러디를 npm 버전으로 만들기도 했음  
    막기 위한 작업이 진행되는 건 훌륭하지만, 그래도 계속 일어남. “또 시작이네” 싶은 의미에서 웃김
  - 모두에게 필수로 만들면 그때야 뭔가 한 셈이 됨
  - 기계적인 변경에는 별로 감명받지 않고, 이 문제를 **문화적 문제**로 보는 집단이 있는 것 같음  
    밖에서 보면 웹 개발은 정신없는 서부 개척지 같은 에너지가 있음. 가변성, 동적 타입, 계속 바뀌는 표준과 프레임워크, 지속 배포, CDN, 실시간 A/B 캠페인, 많은 의존성, 여러 인프라에 퍼진 민감한 사용자 데이터가 있음  
    이 관점이 정확하다고 말하는 건 아니고 “거봐라” 식 태도가 맞다고도 생각하지 않지만, 어디서 나오는지는 이해됨
  - 내 생각엔 둘 다 **돼지에 립스틱** 바르는 해결책임. 결국 전부 “릴리스를 더 어렵게 배포하게 만들자”의 변형이고, 사람들에게 우회법만 학습시킬 뿐임  
    특히 둘 중 어느 것도 xz-utils 백도어가 패키지 배포에 들어가는 걸 막지 못했을 것임. xz-utils는 정교한 상류 침해의 기준점으로 남아 있음  
    여기서 버그는 이미 신뢰한 상류를 더 잘 인증해야 한다는 게 아니라, 상류를 보안의 유일한 출처로 신뢰할 수 없다는 것임. 상류는 견고한 릴리스 엔지니어링에 관심도 적고 잘하지도 못할 해커들의 집단임  
    하지만 그걸 잘하는 사람들도 있음. Linux 세계의 해법이자 xz-utils에서 우리를 구한 방식은, 해커가 만든 상류를 사용자를 위해 검토·감사·패키징·커스터마이즈하는 **두 번째 인간 계층**이 있다는 것임  
    이 사람들은 다른 눈, 다른 소비자 요구, 다른 품질 기준을 갖고 있고, 상류가 잡을 준비가 안 된 버그와 악의를 잡아냄  
    NPM, cargo, PyPI 등은 이 인간 노동 요구를 우회할 수 있다고 계속 생각하지만, 그럴 수 없음. NPM 생태계는 특히 매우 빠른 릴리스, 느슨한 호환성 요구, 극단적인 재사용에 익숙한 웹 개발자들이 많아 node 패키지에서 Python이나 Rust보다 이런 일이 더 자주 보이는 이유가 됨

- 우리 회사는 **yarn 4**를 쓰는데, npm 패키지가 릴리스된 뒤 처음 며칠 동안 설치를 막는 옵션이 있음. 이런 공격 대부분은 그 기간(1~3일) 안에 잡히는 듯함  
  [https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e...](<https://gist.github.com/mcollina/b294a6c39ee700d24073c0e5a4e93104>)
  - event-stream 패키지는 침해되고도 60일 동안 발견되지 않았음: [https://medium.com/intrinsic-blog/compromised-npm-package-ev...](<https://medium.com/intrinsic-blog/compromised-npm-package-event-stream-d47d08605502>)  
    axios 패키지는 침해됐고, 작성자의 자격 증명도 탈취돼서 수정 시도마다 다시 무력화됐음: [https://www.trendmicro.com/en_us/research/26/c/axios-npm-pac...](<https://www.trendmicro.com/en_us/research/26/c/axios-npm-package-compromised.html>)  
    xz 유틸리티는 2개월 동안 백도어가 들어가 있었음: [https://gigazine.net/gsc_news/en/20240403-timeline-of-xz-ope...](<https://gigazine.net/gsc_news/en/20240403-timeline-of-xz-open-source-attack>)  
    한 학생 연구자는 Python ctx와 PHPass 패키지 유지보수권을 넘겨받아 악성 변경을 배포했고, 탐지와 수정까지 7일 넘게 걸렸음: [https://infosecwriteups.com/how-i-hacked-ctx-and-phpass-modu...](<https://infosecwriteups.com/how-i-hacked-ctx-and-phpass-modules-656638c6ec5e>)  
    Kaspersky는 1년 넘게 악용된 여러 PyPI 패키지를 발견했음: [https://www.kaspersky.com/about/press-releases/kaspersky-unc...](<https://www.kaspersky.com/about/press-releases/kaspersky-uncovers-year-long-pypi-supply-chain-attack-using-ai-chatbot-tools-as-lure>)  
    “LoftyLife” 패키지는 몇 달 동안 악용됐음: [https://securelist.com/lofylife-malicious-npm-packages/10701...](<https://securelist.com/lofylife-malicious-npm-packages/107014/>)  
    공격 창이 7일로 바뀌면, 이런 새 공격들은 모두 8일째까지 발동하지 않는 **시한폭탄**을 넣게 될 것임
  - `pnpm`도 같은 기능이 있고, `v11`부터 기본으로 켜져 있음: [https://pnpm.io/settings#minimumreleaseage](<https://pnpm.io/settings#minimumreleaseage>)
  - Python 개발자라면 uv도 같은 기능을 지원함: [https://docs.astral.sh/uv/concepts/resolution/#dependency-co...](<https://docs.astral.sh/uv/concepts/resolution/#dependency-cooldowns>)
  - 모든 패키지를 항상 최신이자 최고 상태로 유지해야 한다는 발상은 다시 생각해볼 만함. 모든 마이너 버전 업데이트를 즉시 적용할 필요는 없고, 높은/치명적 취약점도 꼭 **마이너 버전 업그레이드**일 필요는 없을 수 있음
  - 모두가 3일 지연을 시작하면, 결국 모두가 3일째에 발견하게 되는 것 아닐까?

- 몇 가지 제안이 있음. **의존성 쿨다운** 1~2일은 CVE 패치 능력을 해치지 않으면서 매우 효과적인 듯함  
  `npm install`, `npm test`처럼 코드가 실행되는 곳은 모두 권한 없는 환경에서 돌아가야 함. GitHub Actions에서는 아티팩트를 빌드·테스트하는 작업과 배포·서명 등을 하는 작업을 분리하면 비교적 간단함. AI를 쓴다면 이 패턴을 강제하는 skill/가이드를 추가하면 됨  
  GitHub Actions를 쓴다면 최신 zizmor를 설치하면 보안 태세가 크게 좋아짐  
  두 번째 조치는 더 이상 “웜처럼 전파 가능”하지 않게 해주며, 지금 문제의 큰 부분을 줄여줌. 첫 번째는 회사들이 공격에 대응할 시간을 벌어줌. 이 분야의 몇몇 벤더도 평가해볼 만함
  - zizmor가 침해되면 어떻게 하나?  
    새 패키지는 지연해야 한다고 말한 직후라 농담처럼 웃겼음
  - 이런 쿨다운 대신 **격리된 컨텍스트**에서 빌드를 실행하면 되는 것 아닐까?  
    로컬에서 Maven 프록시를 돌리고, 모든 빌드는 컨테이너 안에서 함. Python, npm, Go는 공개 저장소만 쓰므로 이 빌드들도 컨테이너에서 하되 저장소 프록시는 필요 없음
  - 코드가 실행되는 모든 곳이라면 codex, claude-code 같은 **에이전트형 오케스트레이터**들이 기본으로 그렇게 하는 것 같음

- Red Hat과 IBM이 공급망 취약점 탐지·수정을 돕는 **Project Lightwell**을 발표한 날과 같은 날이네  
  [https://www.redhat.com/en/lightwell](<https://www.redhat.com/en/lightwell>)
  - 그건 며칠 전이었음: [https://news.ycombinator.com/item?id=48313577](<https://news.ycombinator.com/item?id=48313577>)

- 며칠 전 이 흥미로운 rant를 봤음: [https://github.com/uNetworking/uWebSockets.js/blob/master/mi...](<https://github.com/uNetworking/uWebSockets.js/blob/master/misc/npm.md>)  
  올바른 방식은 쓰는 모든 의존성을 포크하고, 필요할 때 상류를 검토·병합하면서 자기 저장소에서 설치하는 것이라는 말이 일리는 있음. 다만 엄청나게 귀찮을 것 같음
  - 자동화 못 할 일은 아님. Go 쪽에서는 이를 vendoring이라고 부를 수 있음: [https://go.dev/ref/mod#vendoring](<https://go.dev/ref/mod#vendoring>)  
    제3자 의존성 호스팅 업체 의존을 줄이거나 덜어내고, 의존성을 자기 코드 리뷰 도구 안으로 가져오며, 장기적으로 **재현 가능한 빌드**를 보장하는 데 좋음
  - 문제는 의존성의 의존성, 그리고 그 아래 여러 단계까지 계속 이어진다는 것임
  - CLI에서 의존성을 쉽게 감사하려고 **Packj**를 만들었음  
    Packj([https://github.com/ossillate-inc/packj](<https://github.com/ossillate-inc/packj>))는 행위 분석으로 악성 PyPI/NPM/Ruby/PHP 등의 의존성을 탐지함. 정적+동적 코드 분석으로 셸 실행, SSH 키 사용, 네트워크 통신, decode+eval 사용 같은 침해 지표를 스캔함. 오타 스쿼팅 같은 악성 행위자를 찾기 위해 여러 메타데이터 속성도 확인함
  - 확률은 바꿀 수 있겠지만, 성실하게 포크하고 앞으로의 모든 취약점에 monkeypatch하지 않으면 **침해된 포크**를 영원히 배포하게 될 수도 있음
  - 패키지를 최신으로만 두지 말고 버전 번호도 제한해야 하지 않나?

- 약 일주일 전에 노트북에서 Node를 지웠고, 기분이 좋았음  
  운 나쁘게 익스플로잇을 맞더라도 피해 반경을 줄이려고 모든 작업을 **개발 컨테이너**나 다른 샌드박스에서 하려는 중임. 공격자가 Claude 토큰을 가져갈 수는 있겠지만, 컨테이너를 쉽게 탈출해 홈 디렉터리를 훑지는 못할 것임  
  쿨다운과 설치 스크립트 허용 목록은 특히 CI에서 계층형 보안에 좋은 추가 장치임. 하지만 근본적으로 바뀌어야 할 것은 운영체제 권한 모델이라고 봄. 서드파티 소프트웨어를 사용자 권한 전체로 신뢰하는 기본값은 더 이상 작동하지 않음
  - Bubblewrap/Firejail/Flatpak 같은 걸 쓰는지, 아니면 그런 설정이 어떤 모습인지 궁금함. 비슷한 아이디어를 한동안 생각만 하고 아직 실행은 못 했음

- 원래 발표 링크를 걸어야 할 것 같음  
  [https://www.stepsecurity.io/blog/multiple-redhat-cloud-servi...](<https://www.stepsecurity.io/blog/multiple-redhat-cloud-services-npm-packages-compromised>)
  - 맞음. 그리고 제목에서 Red Hat 철자도 틀렸음

- 패키지를 설치할 때 이제 `--before=2026-05-30` 플래그를 쓰는 습관이 생겼음. 지정한 날짜 이전에 릴리스된 버전을 고르게 하고, 보통 5일 전쯤을 선택함
  - npm 11을 쓰면 **min-release-age**를 5로 설정해서 흐름을 단순화할 수 있음  
    [https://docs.npmjs.com/cli/v11/using-npm/config#min-release-...](<https://docs.npmjs.com/cli/v11/using-npm/config#min-release-age>)
  - 나는 `pnpm`을 쓰고 넉넉한 `minimumReleaseAge`를 설정함  
    [https://pnpm.io/settings#minimumreleaseage](<https://pnpm.io/settings#minimumreleaseage>)  
    다행히 v11부터 기본으로 켜져 있음
  - 순수 npm(v11.10.0 이상)을 쓰면 프로젝트 루트의 `.npmrc`에 그냥 `min-release-age=5`를 추가하면 됨
  - Yarn 4는 이걸 자동화할 수 있음

- **NPM은 설계부터 망가졌고**, 커뮤니티에 만연한 NIH 증후군 때문에 단순한 조치도 못 하게 됨
  - 두 번째 문장은 잘 이해가 안 됨. npm은 ‘여기서 만든 게 아니면 안 씀’의 반대 문제 아닌가?  
    자체 개발보다 외부 패키지를 많이 받아들이다 보니 npm 프로젝트는 크고 복잡한 의존성 트리를 갖는 경향이 있음. [https://www.npmjs.com/package/is-windows](<https://www.npmjs.com/package/is-windows>) 같은 패키지는 같은 코드를 직접 쓰기 너무 쉬운데도 잠재 취약점과 유지보수 골칫거리를 만든다는 불만이 오래전부터 있었음
  - NIH 쪽에서 흔한 오류는 X 패키지를 다시 만드는 데 시간이 많이 걸릴 거라는 생각임  
    하지만 당연히 모든 기능을 다시 만들 필요는 없고, 필요한 기능만 만들면 됨  
    게다가 기능 하나만 코딩할 때는 추상화나 추가 함수 인터페이스를 만들 필요도 없음. 그래서 더 싸고, 아마 더 잘 통합됨  
    또 다른 오류는 버그와 취약점을 만들 거라는 생각임. 나쁜 프로그래머라면 그럴 수도 있지만, 서로 정확히 맞도록 설계되지 않은 두 라이브러리의 통합 경계에서 생기는 취약점 범주는 피할 수 있음. 그런 경우가 많음
