Mini Shai-Hulud가 다시 공격: npm 패키지 314개 침해
(safedep.io)- atool npm 계정이 2026년 5월 19일 침해되어 약 22분 동안 317개 패키지에 637개 악성 버전이 자동 배포됨
- 페이로드는 498KB 난독화 Bun 스크립트로, SAP 침해에 쓰인 Mini Shai-Hulud와 같은 스캐너 구조와 정규식을 사용함
- 탈취 대상은 AWS 자격 증명, Kubernetes 토큰, Vault, GitHub PAT, npm 토큰, SSH 키, 로컬 비밀 값까지 확장됨
- CI에서는 GitHub Actions OIDC를 npm publish 토큰으로 교환하고, Sigstore 서명과 악성 workflow 주입을 악용함
- 대응에는 침해 버전 설치 여부 확인, 접근 가능했던 모든 자격 증명 교체, lockfile·의존성 pinning과 설치 전 검사가 필요함
공격 개요
atoolnpm 계정(i@hust.cc)이 2026년 5월 19일 침해되어 약 22분 동안 317개 패키지에 637개 악성 버전이 배포됨- 이 계정은 547개 패키지를 유지하고 있었고, 공격자는 그중 314개 이상에 두 차례 버전 bump를 수행함
- 영향 패키지에는
size-sensor(월 420만 다운로드),echarts-for-react(380만),@antv/scale(220만),timeago.js(115만), 다수의@antv스코프 패키지가 포함됨 - 페이로드는 498KB 난독화 Bun 스크립트이며, 3주 전 SAP 침해에 사용된 Mini Shai-Hulud toolkit과 같은 스캐너 구조, 자격 증명 정규식, 난독화 패턴을 사용함
- 탈취 데이터는 공개 GitHub 저장소에 Git 객체로 커밋되거나, RSA+AES로 암호화된 HTTPS POST로
t.m-kosche[.]com에 전송됨
배포 방식과 semver 위험
- 첫 번째 파동은 2026년 5월 19일 01:39~01:56 UTC에 약 317개 버전을 배포했고, 두 번째 파동은 02:05~02:06 UTC에 같은 패키지들에 약 314개 버전 bump를 수행함
- 대부분의 패키지 309개는 파동마다 하나씩 정확히 2개의 악성 버전을 받음
size-sensor,echarts-for-react,jest-canvas-mock,jest-date-mock4개 패키지는 3개 버전을 받아 초기 테스트에 쓰인 것으로 나타남- 공격자는 대부분의 패키지에서
latestdist-tag를 이동하지 않았지만, npm semver 해석은latest와 무관하게 범위에 맞는 가장 높은 버전을 선택함 - 예를 들어
echarts-for-react의latest가3.0.6에 남아 있어도,"echarts-for-react": "^3.0.6"인 프로젝트는 다음 clean install에서 악성 버전3.2.7로 해석될 수 있음
실행 경로와 페이로드
- 손상된 모든 버전은
package.json에 버전 bump와"preinstall": "bun run index.js"를 추가함 - 637개 악성 버전 중 630개는
optionalDependencies에@antv/setup: github:antvis/G2#<commit-sha>를 추가해 두 번째 페이로드 사본을 가져오게 함 preinstall훅은 의존성 설치 전에 실행되며 Bun 런타임을 요구함preinstall이 차단되거나 건너뛰어져도 GitHub 사칭 커밋의prepare스크립트가 두 번째 실행 경로로 남음index.js는 한 줄짜리 498KB 난독화 Bun 번들이며, SAP 침해에 쓰인 Mini Shai-Hulud payload와 같은 Bun 요구 사항, hex-variable 난독화, 100KB flush threshold 스캐너 구조, 자격 증명 정규식 세트를 가짐- CI 환경 감지는 GitHub Actions, Jenkins, GitLab CI, CircleCI, Travis, Buildkite, Drone, TeamCity, AppVeyor, Bitbucket Pipelines, CodeBuild, Azure DevOps, Netlify, Vercel 등 20개 이상 플랫폼의 환경 변수를 확인함
자격 증명 수집 대상
- 페이로드는 암호화된 이름의 환경 변수 80개 이상을 읽고, 파일 내용은 정규식으로 스캔함
- 주요 대상은 GitHub token, npm token, GitHub Actions JWT, AWS key, Azure key, DB connection string, Stripe key, SSH key, Docker auth, Vault token, Kubernetes token, URL embedded credential임
- 파일 스캐너는 홈 디렉터리의
.ssh,.aws/credentials,.npmrc,.docker/config.json,.kube/config같은 표준 자격 증명 위치를 읽음 - AWS credential resolution order 전체를 순회하고, EC2 IMDSv2와 ECS container credential endpoint에서 IAM role credential을 가져오며, AWS STS
GetCallerIdentity와 Secrets Manager 접근도 시도함 - Vault는 token 파일과
VAULT_ADDR,VAULT_TOKEN,VAULT_ROLE등을 확인하고, 유효한 credential이 있으면 secret 열거와 AWS·Kubernetes 인증을 시도함 - Kubernetes는 service account token과
KUBECONFIG를 확인하며, Docker socket이 있으면 host의 컨테이너 열거와 컨테이너 탈출을 시도함
C2와 데이터 유출
- GitHub API는 C2처럼 사용되며,
GET /user로 탈취한 GitHub 토큰을 검증하고GET /user/orgs로 조직을 열거함 repo또는public_repo권한이 충분한 토큰은 공격자 유출 저장소 생성에 사용됨- 생성 저장소 설명은 역순 문자열
niagA oG eW ereH :duluH-iahS로 저장되어, 정방향으로 “Shai-Hulud: Here We Go Again”이 됨 - 저장소 이름은
harkonnen-melange-742,fremen-sandworm-315,gesserit-navigator-508처럼 Dune 테마 단어 2개와 숫자를 조합함 - 유출 데이터는 Git Data API를 통해 blob, tree, commit, ref update 순서로 저장됨
- 별도 HTTPS sender는
hxxps://t.m-kosche[.]com/api/public/otel/v1/traces를 OpenTelemetry OTLP trace ingestion endpoint처럼 보이게 구성함 - HTTPS payload는 gzip JSON을 AES-256-GCM으로 암호화하고, AES key를 하드코딩된 공개키로 RSA-OAEP wrapping함
CI/CD와 신뢰 체인 악용
- 탈취한 토큰이 접근 가능한 GitHub 저장소에서 workflow 실행 이력, artifact, secret 이름, branch 목록, Claude Code 설정을 수집함
- GitHub API로 secret 값에는 접근할 수 없지만, secret 이름은 어떤 자격 증명이 존재하는지 드러냄
- 악성 workflow는
.github/workflows/codeql.yml에 주입되며, 이름은Run Copilot이고push에 트리거됨 - workflow는
VARIABLE_STORE: ${{ toJSON(secrets) }}로 repository secrets 전체를 JSON으로 환경 변수에 담고,format-results.txt로 저장한 뒤 artifact로 업로드함 - 완료 후 artifact zip을 다운로드하고, workflow run 삭제와 branch ref reset으로 주입 흔적을 줄임
- GitHub Actions OIDC가 있는 CI에서는
https://registry.npmjs.org/-/npm/…;endpoint로 npm publish token 교환을 시도함 - 페이로드는 Fulcio, Rekor, SLSA provenance 형식을 포함한 Sigstore signing 구현을 갖고 있어, 침해된 CI identity로 서명된 artifact를 만들 수 있음
개발 환경과 AI 코딩 에이전트 감염
- 페이로드는 GitHub API를 통한 원격 주입과 파일시스템 쓰기를 통한 로컬 감염으로 Claude Code, Codex, VS Code 환경을 겨냥함
- 탈취한 토큰으로 접근 가능한 저장소에
.vscode/tasks.json,.claude/index.js,.claude/settings.json,.claude/setup.mjs,.vscode/setup.mjs를 커밋함 .claude/settings.json은SessionStart훅을 등록해 Claude Code 세션 시작 때마다node .claude/setup.mjs를 실행함.vscode/tasks.json은"runOn": "folderOpen"으로 프로젝트 폴더가 열릴 때 실행을 트리거함setup.mjs는 GitHub 공식 릴리스에서 Bun v1.3.14를 다운로드하고 바이너리를 추출한 뒤 페이로드를 실행함- 로컬 감염 경로는 페이로드를
~/.claude/package/index.js와~/.codex/package/index.js에 복사하고, 기존 프로젝트 설정 파일을 스캔해 훅을 주입함 - Apple Silicon Mac에서는 이 로컬 감염 경로가 건너뛰어지며, Linux, Intel Mac, Windows에서는 실행됨
지속성과 GitHub dead-drop C2
kitty-monitor로 위장한 지속 실행 데몬이 Linux에서는 systemd 사용자 서비스로, macOS에서는~/Library/LaunchAgents/com.user.kitty-monitor.plist로 설치됨- 설치기는
systemctl --user enable --now와loginctl enable-linger를 사용해 로그아웃 후에도 유지되게 함 cat.py데몬은 1시간마다 GitHub Search API를 폴링하며,firedalazer키워드를 포함한 커밋을 검색함- 커밋 메시지 형식은
firedalazer <base64_url>.<base64_signature>이고, 하드코딩된 4096비트 RSA 공개키로 RSA-PSS 서명을 검증한 뒤 URL의 Python 코드를 실행함 - 별도
gh-token-monitor데몬은 탈취한 GitHub 토큰을 60초 간격으로 폴링하며 TTL은 24시간임 - 프로세스 메모리 스캐너는 Linux에서
/proc/pid/maps+mem, Windows에서ReadProcessMemory를 사용해 GitHub Actions runner worker 프로세스의 읽기 가능한 메모리 영역을 덤프함
antvis/G2 사칭 커밋
- 637개 악성 버전 중 630개는
antvis/G2저장소의 특정 커밋을 가리키는optionalDependencies항목을 포함함{ "optionalDependencies": { "@antv/setup": "github:antvis/G2#1916faa365f2788b6e193514872d51a242876569" } } - npm이
github:의존성을 해석하면 해당 커밋을 가져오고,package.json을 찾은 뒤 라이프사이클 스크립트를 실행함 - 해당 커밋에는
@antv/setup을 선언하고prepare스크립트를 포함한package.json과 같은 Shai-Hulud 페이로드를 다시 난독화한 499KBindex.js가 있음 prepare스크립트의&& exit 1은 optional dependency를 실패하게 만들지만, npm은 optional dependency 실패를 치명적으로 처리하지 않아 설치가 계속됨- Git API는
antvis/G2에 푸시된 서로 다른 커밋 SHA 3개를 보여주며, 모두 어떤 브랜치에도 붙어 있지 않음 - 세 커밋은 author
huiyu.zjt <Alexzjt@users.noreply.github.com>, commit messageNew Package, parents 0개라는 동일한 메타데이터를 공유하며 GPG 서명이 없음 - 공격자는
antvis/G2에 쓰기 권한 없이 fork에 payload orphan commit을 만들고 fork를 삭제하는 방식으로 부모 저장소 namespace에서 SHA fetch가 가능한 커밋을 남길 수 있음 - 이 방식은 GitHub Actions의 사칭 커밋 문제를 Chainguard가 문서화한 것과 같은 종류이며, 여기서는 npm
github:의존성 해석에 적용됨
침해 지표
- 2026년 5월 19일 01:44~02:06 UTC 사이
atool(i@hust.cc)이 배포한 패키지가 확인 대상임 preinstall스크립트는bun run index.js임- 페이로드 SHA256은
a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1c임 antvis/G2사칭 커밋은 다음과 같음1916faa365f2788b6e193514872d51a242876569— 626개 버전7cb42f57561c321ecb09b4552802ae0ac55b3a7a— 2개 버전dc3d62a2181beb9f326952a2d212900c94f2e13d— 1개 버전, garbage collected
- 네트워크 IoC에는
hxxps://t.m-kosche[.]com/api/public/otel/v1/traces,169.254.169.254EC2 metadata,169.254.170.2ECS container metadata 요청이 포함됨 - 저장소 IoC에는
chore/add-codeql-static-analysis브랜치,Run Copilotworkflow,toJSON(secrets)를format-results.txt로 덤프하는.github/workflows/codeql.yml이 포함됨 - 개발 환경 IoC에는
.claude/settings.json의SessionStart훅,.vscode/tasks.json의"runOn": "folderOpen",.claude/setup.mjs,.vscode/setup.mjs가 포함됨 - 지속성 IoC에는
kitty-monitor.service,com.user.kitty-monitor.plist,~/.local/bin/gh-token-monitor.sh,~/.local/share/kitty/cat.py,/var/tmp/.gh_update_state가 포함됨
확인해야 할 대표 패키지
compromised-packages.csv표에는 Package와 Compromised Versions 2개 열이 있으며, 표 기준 317개 패키지가 표시됨- lockfile에서 해당 패키지와 2026-05-19에 배포된 악성 버전 존재 여부를 확인해야 함
- 대표
@antv패키지와 악성 버전@antv/g2:5.5.8,5.6.8@antv/g6:5.2.1,5.3.1@antv/g:6.4.1,6.5.1@antv/l7:2.26.10,2.27.10@antv/x6:3.2.7,3.3.7@antv/s2:2.8.1,2.9.1@antv/f2:5.15.0,5.16.0
- 일반 npm 패키지와 악성 버전
echarts-for-react:3.0.7,3.1.7,3.2.7size-sensor:1.0.4,1.1.4,1.2.4jest-canvas-mock:2.5.3,2.6.3,2.7.3jest-date-mock:1.0.11,1.1.11,1.2.11timeago.js:4.1.2,4.2.2timeago-react:3.1.7,3.2.7@lint-md/cli:2.1.0,2.2.0@lint-md/core:2.1.0,2.2.0@lint-md/parser:0.1.14,0.2.14
대응과 방어
- 침해 버전이 설치됐다면 빌드 환경에서 접근 가능했던 npm 토큰, GitHub PAT, AWS 키, SSH 키, 클라우드 자격 증명, 데이터베이스 비밀번호, Vault 토큰, Kubernetes service account 토큰, 로컬 비밀번호 관리자 비밀 값을 교체해야 함
t.m-kosche[.]com은 네트워크와 DNS 수준에서 차단해야 함- 빌드 환경에서 접근 가능한 토큰을 가진 GitHub 계정 아래에 승인되지 않은 공개 저장소가 생성됐는지 확인해야 함
- CI 파이프라인에서 승인되지 않은 패키지 publish와 npm OIDC 토큰 교환 로그를 검토해야 함
- 침해된 CI identity로 생성된 서명 artifact가 있는지 Sigstore 투명성 로그를 확인해야 함
- 로컬 Node.js 프로젝트에서
.claude/settings.json훅,.vscode/tasks.json자동 실행 작업,.claude/setup.mjs,.vscode/setup.mjs를 확인해야 함 kitty-monitorsystemd 사용자 서비스와com.user.kitty-monitorLaunchAgent를 제거하고,~/.local/share/kitty/cat.py,/var/tmp/.gh_update_state,~/.local/bin/gh-token-monitor.sh존재 여부를 확인해야 함- semver 범위 해석이 악성 버전으로 이어지지 않도록 의존성을 pin하거나 lockfile을 사용해야 함
- CI/CD 파이프라인에서 Docker socket 노출과 EC2 metadata 접근을 감사하고, IMDSv2 hop limit 제한을 고려해야 함
- Package Manager Guard (pmg)는
preinstall실행 전에 패키지를 threat intelligence와 대조하는 오픈소스 설치 프록시임 - dependency cooldown은 설정 가능한 시간 창 안에 배포된 버전을 거부해, semver 범위가 새 악성 릴리스로 해석되는 급격한 배포 파동을 줄일 수 있음
- vet은 예상치 못한
preinstall훅, 크기 급증, maintainer 변경 같은 비정상 패키지 업데이트를 CI/CD 파이프라인에 도달하기 전에 탐지할 수 있음 - 단일 계정 아래 547개 패키지, 한 세션에서 무기화된 314개 이상 패키지라는 영향 범위는 npm 신뢰 모델의 구조적 약점을 드러냄
참고 자료
- Shai-Hulud Goes Open Source: Static Analysis of the Framework — Datadog Security Labs
- The Shai-Hulud Code Drop — ReversingLabs
댓글과 토론
Hacker News 의견들
-
이제 NPM 생명주기 스크립트는 기본으로 비활성화해야 함
편의 기능이라는 명목으로 임의 코드 실행을 내장해 둔 셈이고, 전이 의존성에도 적용됨. 널리 퍼진 NPM 웜식 공격은 모두 이 기본 설정을 통해 전파됐음. 특정 명령에서 한 번 켠다고 모든 전이 의존성이 생명주기 스크립트를 실행할 수 있게 하면 안 되고, 꼭 필요한 의존성마다 명시적으로 표시하게 해야 함
NPM 패키지의 압도적 다수는 이런 스크립트에 의존하지 않으니, 아직 안 했다면 전역으로 꺼두는 게 좋음- 이에 대한 RFC가 있음: https://github.com/npm/rfcs/pull/868
- 아니면 그냥 pnpm을 쓰면 됨
- 맞음. 아니면 샌드박스 안에서 실행돼야 함. 설치된 패키지 자체의 문맥에서 임의 명령을 실행하는 설치 후 스크립트라면 괜찮지만, 임의 스크립트와 사용자 권한의 조합은 재앙의 공식임
다만 패키지는 프로그램에서 처음 가져올 때도 원하는 쓰레기를 실행할 수는 있음
-
“막을 방법이 없다”는 말은 이런 일이 정기적으로 벌어지는 유일한 패키지 관리자에서나 나옴
- NPM이 가장 인기 있는 패키지 관리자라는 점 말고, 이런 공격에 특히 취약하게 만드는 요소가 따로 있나?
-
어느 시점부터는 Dependabot을 끄고 NPM 패키지를 마이너/패치 버전까지 전부 고정하는 편이 계속 업데이트하는 것보다 나을 수 있지 않을까
특히 프런트엔드 패키지에서는 요즘 의미 있는 보안 수정이 공급망 공격보다 덜 흔해 보임
슬픈 상황이지만, 프런트엔드를 정적 BOM으로 바꾸고 NPM이 최소한 “이전 버전으로 다시 배포할 수 없다”는 제약만 제대로 지킨다고 믿으면 안 되는 이유가 있을까?- 그러면 패치가 있는 CVSS 3.1짜리 CVE 하나가 미수정으로 남아 있다고 컴플라이언스 팀이 짜증 냄
- 숙성 기간을 강제하면 됨. 예를 들어 30일보다 새 버전은 어떤 풀 리퀘스트도 못 들여오게 하는 식임
알려진 CVE를 해결하는 버전에는 예외를 둘 수 있음 - 맞음. 다른 생태계에서 공급망 공격이 덜 보이는 이유 중 하나가 그거임
- NPM은 해시와 고정된 전이 의존성까지 포함한 완전한 lockfile을 만들지 않나?
-
상황이 점점 미쳐가고 있음. 개인적으로는 이미 내 머신에서 node, python, 모든 패키지 관리자를 제거했고, 대신 devcontainer나 VM 안에서만 씀
개발자 커뮤니티가 매우 강화된 보안을 만들어낸다 해도, 적어도 1년쯤 뒤에는 모델의 사회공학 능력이 충분히 좋아져서 여전히 지는 게임을 하고 있을까 봐 걱정됨- 모델이 사회공학에 아주 능숙해지면 왜 원칙적으로 그렇게 큰 영향이 생긴다고 보는지 모르겠음. 수익 체감이 있고, 대상이 인간 속도로 움직인다는 병목이 매우 커 보임
예를 들어 XZ 해킹에 들어간 노력은 막대했고, 기존 관리자를 시간에 걸쳐 지치게 만드는 방식이었기 때문에 가속할 수 없었음. 필요한 악성 메시지를 몇 초 만에 만들고 보낼 수는 있어도 그것을 읽는 인간의 속도는 빨라지지 않으며, 한꺼번에 도착하면 오히려 의심을 살 것임
입력이 설득력을 가질 수 있는 데도 한계가 있음. XZ 관리자에게 향한 임의의 악성 메시지를 하나 골라 더 악랄하고, 더 정확하고, 관리자의 개인적 약점과 두려움을 더 잘 반영하게 만들 수는 있겠지만, 전체적으로 더 효과적이었을까? 아니거나, 많아야 아주 조금일 것 같음 - 컨테이너가 이 문제를 어떻게 해결함? 인터넷에 연결돼 있다면, 그리고 실제로 그렇다면, 컨테이너가 자격 증명을 읽을 수 있는 한 같은 문제가 생기는 것 아닌가
- node 없이 클라우드 리소스는 어떻게 제어함? Cloudflare는 wrangler가 필요하고, AWS에도 node CLI가 많음
- 모델이 사회공학에 아주 능숙해지면 왜 원칙적으로 그렇게 큰 영향이 생긴다고 보는지 모르겠음. 수익 체감이 있고, 대상이 인간 속도로 움직인다는 병목이 매우 커 보임
-
이제 Zed가 1.0이 됐으니 완전히 갈아타고 싶지만, 내가 알기로 보안 모델이 전부 아니면 전무임. 내가 모르는 NPM 패키지를 마음대로 내려받고 설치하도록 허용하거나, 모든 LSP 기능을 꺼야 함
그런데 이런 뉴스가 계속 보임 -
npm이 패키지 업로드를 자동으로 약 10분 지연시키고, 그 사이에 제3자 코드 감사 회사 생태계로 배포해 자동 검사를 받게 하는 프로그램을 운영할 수 있지 않을까
어떤 감사자가 문제를 가장 빠르고 안정적으로 잡는지 공개 순위표를 만들거나, 금전 보상을 줄 수도 있음 -
이 목록은 불완전함. 적어도 다른 패키지 하나, nx-console VS Code 확장도 어제 이 웜에 감염됐고 다운로드가 220만 회임
자격과 연결망이 있는 사람이 읽고 있다면, 더 있는지 확인하기 위해 그 의존성 사슬도 따라가 볼 가치가 있음. 여기 참고:
https://github.com/nrwl/nx-console/security/advisories/GHSA-...
PS: 감염 직후 사람들에게 알리려고 HN에 올렸지만, 안타깝게도 거의 추천을 못 받았음 -
전체 생태계를 놓고 보면 TC39가 JS 자체에 더 나은 표준 라이브러리를 추가하는 방안을 봐야 함. 그러면 한 줄짜리 패키지 수를 줄일 수 있음
동의함. 예전 Deno로 작업할 때 가장 좋았던 부분은 표준 라이브러리[0]와 전반적으로 완결된 개발 환경이었음. 런타임에 통합 테스트 실행기와 단언 라이브러리가 들어있는 건 너무 당연함
0 - https://docs.deno.com/runtime/reference/std/- 공정하게 말하면 Node도 여러 LTS 버전 전부터 기본으로
node:test[0]와node:assert/strict[1] 모듈을 제공함.node --test는 Mocha를 쉽게 대체할 수 있고,node:assert/strict도 괜찮지만chai가 가끔 더 편함.expect같은 사용성 때문임. Deno의 @std에는expect스타일 단언 라이브러리가 있음
문제는 Node 생태계에 테스트 실행기가 너무 많고, 그중 상당수는 Mocha처럼 쉽게 대체되지 않는다는 것임. 그래서 기본 제공 테스트 하네스와 단언 라이브러리로 옮겨가는 과정은 당연히 고통스럽게 느릴 것임. 사람들은 여러 이유로 Jest와 Vitest의 과하게 복잡한 성격을 좋아함. 대기업들은 Karma가 좋은 아이디어라고 생각했음. “단위 테스트에 V8을 좋아한다면서요? 그럼 기존 V8 환경에서 또 다른 V8 사본을 하나 더 띄워드리죠”라는 느낌에 왜 더 많은 개발자가 질색하지 않았는지 아직도 이해가 안 됨
[0] https://nodejs.org/api/test.html
[1] https://nodejs.org/api/assert.html#strict-assertion-mode - 여기 나온 패키지 중 어떤 것이 “더 나은 표준 라이브러리”에 들어갈지는 잘 모르겠음
어떤 언어 표준 라이브러리에 “3시간 전” 형식 변환기가 있나? timeago.js가 하는 일이 그거임
slice.js는 Python식 음수 인덱싱을 제공할 뿐임. TC39는 이미 array.at()과 array.slice()가 음수를 처리하게 만들었음 - 요즘 Node.js 표준 라이브러리도 계속 커지고 있고, 앞서 말한 단언과 테스트 지원을 포함한다는 점은 짚을 만함
https://nodejs.org/api/
- 공정하게 말하면 Node도 여러 LTS 버전 전부터 기본으로
-
페이로드가 Docker 소켓을 확인하고, 있으면 세 가지 순차 방법으로 컨테이너 탈출을 시도한다는 얘기임
그러니 devcontainer나 VM 안에서 실행해도, 이런 웜은 이미 빠져나오려고 시도하고 있음
rootless VM 엔진을 쓰는지 확인해야 함. 예를 들어 Docker 대신 podman 같은 것- 일부 사람들, 심지어 보안 업계 사람들까지 다르게 말하지만, Docker는 강한 보안 경계가 아니며 그렇게 취급하면 안 됨. 실행 중인 시스템과 커널을 공유함
예전에 사람들이 낮은 권한의 Linux 계정을 나눠주고 커널이 권한 상승을 막아주리라 믿던 시절이 떠오름. Docker는 말 그대로 같은 일에 절차가 더 붙은 것임. 특히 요즘은 새 커널 로컬 권한 상승 취약점이 5분마다 나오는 수준임
Podman은 공격자에게 root를 넘기지 않는다는 점에서 조금 낫지만, 애초에 왜 계정을 주나? 제대로 된 VM을 쓰면 됨 - 컨테이너 안에 Docker 소켓을 마운트하지 않으면 됨
- jails나 zones에 더 가까운 무언가를 얻었으면 정말 좋았을 것 같음. 더 나아가 컨테이너를 jail이나 zone 안에 넣는 방식이면 좋고
BSD에 있는 것 같은 포괄적 샌드박스가 Linux에도 있나? - 왜 제대로 된 가상 머신을 쓰지 않나?
- 대부분은 Docker를 rootless로 실행하지 않나, 적어도 Linux에서는? podman이 더 하는 게 있나?
- 일부 사람들, 심지어 보안 업계 사람들까지 다르게 말하지만, Docker는 강한 보안 경계가 아니며 그렇게 취급하면 안 됨. 실행 중인 시스템과 커널을 공유함
-
이제 Mr Bones' Wild Ride에서 내리고 싶지만, 이런 일은 계속될 것 같아 두려움. 내가 살펴본 바로는 상용 탐지 전략 상당수가 패키지를 로드하거나 사용할 때 저장소/기기/개발자 수준에 맞춰져 있음
이메일 스팸이나 일반 악성코드를 다루는 방식과 비슷해 보임. 그래서 악성 행위자가 계속 시도할 만큼 가치 있는 대상이 거의 항상 존재함. 하지만 이메일과 달리 패키지 관리자는 중앙화된 권한자이고, 대역 밖 문제는 당연히 개발자 책임으로 밀릴 가능성이 큼
잘 모르는 입장에서 보기엔, 빠른 릴리스와 느슨한 버전 관리 문화에서 벗어나 레지스트리의 안정적이고 깊게 검사된 버전에 집중해야 할지도 모름. 물량과 규모의 효과 때문에 내가 틀릴 수도 있지만, 변동이 큰 언어일수록 더 자주 영향을 받는다는 점은 여전히 시사적임
지금의 지형을 포괄적으로 다루는 글이 있으면 정말 좋겠음- Mr Bones' Wild Ride가 1991년 영화 Nothing But Trouble의 참조일까 싶어 찾아봤는데, 내가 잘못 기억하고 있었음
그 영화의 롤러코스터 이름은 Mr Bonestripper였음: https://www.youtube.com/watch?v=NEZEgd8GjJc
대신 Roller Coaster Tycoon 2에서 나온 것임: https://knowyourmeme.com/memes/mr-bones-wild-ride
스팸과의 비교로 보면, 우리는 거의 모든 상업적·사회적 컴퓨터 네트워크 환경에서 이메일 주소를 빨아들여 스팸을 사람들이 받아들이게 만들고, 거기에 합법성의 외피를 씌우는 쪽으로 어느 정도 정착했음. 이 영역에서도 비슷한 일이 생길 가능성이 큼. 아마 Oracle 라이선스 감시 에이전트식 소프트웨어와 자동 의존성 관리의 조합, 즉 다른 악성코드를 허용 목록에 올려 공급망 악성코드를 “해결”하는 식일 수 있음
- Mr Bones' Wild Ride가 1991년 영화 Nothing But Trouble의 참조일까 싶어 찾아봤는데, 내가 잘못 기억하고 있었음