2P by GN⁺ 9시간전 | ★ favorite | 댓글 1개
  • 딥러닝 프레임워크 lightning2.6.22.6.3 버전이 공급망 공격에 악용됨 — pip install lightning만 실행해도 숨겨진 _runtime 디렉터리의 난독화된 JavaScript 페이로드가 자동 실행
  • 이미지 분류기 구축, LLM 파인튜닝, 확산 모델, 시계열 예측 등에 널리 쓰이는 프레임워크이므로, 많은 AI/ML 팀의 의존성 트리에 이미 포함되어 있을 가능성이 높음
  • 악성코드가 실행되면 로컬 파일시스템에서 80개 이상의 경로를 스캔해 GitHub 토큰(ghp_, gho_), npm 토큰(npm_), 환경 변수, 클라우드 비밀값을 탈취하며, 파일당 최대 5MB까지 처리
  • AWS(자격 증명 파일·IMDSv2·ECS·Secrets Manager·SSM), Azure(Key Vault), GCP(Secret Manager) 등 3대 클라우드 제공자 전체를 대상으로 비밀값을 열거하고 가져옴
  • GitHub Actions 환경에서는 내장 Python으로 Runner.Worker 프로세스 메모리를 덤프"isSecret":true로 표시된 모든 비밀값과 저장소·워크플로 정보를 추출
  • 진입점은 PyPI(Python)이지만 웜 전파는 npm(JavaScript)을 통해 확산 — 탈취한 npm 토큰으로 게시 가능한 모든 패키지에 드로퍼(setup.mjs)와 악성코드(router_runtime.js)를 주입하고 패치 버전을 올려 재게시, 해당 패키지를 설치한 하위 개발자의 머신까지 연쇄 감염
  • 데이터 유출은 단일 경로 차단으로 막을 수 없도록 4개 병렬 채널을 동시에 사용: ① HTTPS POST로 C2 서버 전송, ② GitHub 커밋 검색 API를 이용한 데드드롭(커밋 메시지에 이중 Base64 인코딩 토큰 삽입), ③ Dune 세계관 이름의 공개 GitHub 저장소에 results-<timestamp>.json으로 커밋, ④ 피해자 저장소에 직접 푸시
  • 저장소에 침투한 뒤에는 개발 도구에 지속성 훅을 심어 재감염을 보장 — Claude Code의 .claude/settings.jsonSessionStart 훅을 작성해 세션 시작 시 자동 실행, VS Code의 .vscode/tasks.jsonrunOn: folderOpen 작업을 심어 폴더를 열 때마다 실행
    • 두 훅 모두 자체 포함형 드로퍼 setup.mjs를 호출하며, Bun 런타임이 없으면 GitHub에서 조용히 다운로드해 14.8MB 페이로드 router_runtime.js를 실행
  • 쓰기 권한 GitHub 토큰을 확보하면 피해자 저장소에 Formatter라는 위장 워크플로를 푸시 — 모든 push에서 ${{ toJSON(secrets) }}로 저장소 비밀값을 덤프하고 Actions 아티팩트로 업로드
  • 영향받은 기간에 해당 버전을 설치한 모든 머신은 완전 침해된 것으로 간주해야 하며, GitHub 토큰·클라우드 자격 증명·API 키를 즉시 교체하고 .claude/.vscode/ 디렉터리에 예상치 못한 파일이 없는지 감사 필요
  • 공격 지표: 커밋 메시지에 EveryBoiWeBuildIsAWormyBoi 접두사, 저장소 설명에 "A Mini Shai-Hulud has Appeared", 저장소 내 _runtime/ 디렉터리 존재 여부 등으로 GitHub 검색을 통해 직접 확인 가능
Hacker News 의견들
  • 단순히 빈도 착각일 수도 있지만, 최근 주요 패키지에서 유명한 공급망 공격이 꽤 많이 보임
    지금 HN 첫 몇 페이지에도 서로 다른 사례를 다룬 글이 여러 개 있음
    10년 전 left-pad를 돌아보면, 지금 성공한 공격이 예전보다 더 많은가 싶고 아마 그럴 것 같음
    성공한 공격의 가치도 확실히 커졌을 텐데, 패키지 릴리스 전에 탐지하는 능력은 커뮤니티 전체로서 실제로 나아지고 있는지 궁금함
    상용 소프트웨어 회사는 더 잘해야 하지만, 취미/아마추어 코드로 시작했다가 많은 프로젝트의 의존성이 되는 경우를 위한 보편적이고 쉬운 도구는 아직 부족해 보임
    현재 SAP 공급망 공격 스레드에도 같은 댓글을 올렸음: https://news.ycombinator.com/item?id=47964003

    • 실제 현상임. 4월 초 기준으로 최근 12개월에 7건이 있었고, 그 전 20년 동안은 9건이었음: https://www.jefftk.com/p/more-and-more-extensive-supply-chai...
    • 사람들이 코드를 제대로 보지도 않고 여기저기 대량으로 밀어 넣고 있으니, 그에 따라 공급망 공격이 늘어나는 건 자연스러움
    • 이유는 자동 업데이트와 CI 도구가 임계 보급률에 도달해 모두가 쓰기 때문임
      예전에는 npm install을 수동으로 실행하는 경우가 더 많았고, 빌드가 깨졌을 때나 아주 가끔 실행했을 가능성이 큼
      공급망 공격은 사람들이, 더 정확히는 파이프라인이 새 릴리스가 나오자마자 아무 생각 없이 패키지를 자동 업데이트하는 데 의존함
    • 역사적으로 추가 보안 검사를 거친 산출물 처리는 유료 엔터프라이즈 옵션이었고, 덜 안전한 쪽이 훨씬 번거롭지 않은 기본값이었음
      이게 좋은 비즈니스 모델인지는 모르겠고, 아마 별로 아닐 것 같음
    • left-pad는 공격이 아니라 NPM의 버그였음
      이미 공개된 다른 패키지가 의존하는 패키지 버전을 삭제할 수 있어서는 안 됐고, 반대로 새 버전이면서 아무도 의존하지 않는 특정 패키지 버전은 삭제할 수 있어야 했음
      left-pad 작성자가 서비스를 떠나려는 의도로 모든 데이터를 지우려 했을 때 NPM은 오류 코드를 반환했어야 함
      Wikipedia에 따르면 Koçulu가 npm, Inc.의 결정에 실망해 플랫폼 일부로 남고 싶지 않다고 하자, NPM 작성자인 Schlueter가 그가 등록한 273개 모듈을 삭제하는 명령을 제공했음
  • 이상한 점은 보안 이슈 4개가 올라왔는데 모두 pl-ghost라는 봇이 자동 댓글을 달고 닫았다는 것임 [1][2][3][4]
    결국 이 중 [4]만 제대로 처리됐고 봇 댓글은 모두 삭제됨
    다른 보고서 [5]에서 봇 댓글을 볼 수 있는데, 원문보다 더 많은 정보를 줌
    [1] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [2] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [3] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [4] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
    [5] https://socket.dev/blog/lightning-pypi-package-compromised

    • Lightning의 Andy임. 맞음, PyPI 자격 증명은 침해된 pl-ghost 봇 계정을 통해 도난당했음
      공격자는 이 계정으로 새 Actions 워크플로를 만들었고, 실행된 워크플로에서 PyPI 비밀값을 파싱해 빼냈음
      패키지를 릴리스한 뒤에는 그 계정으로 댓글을 달며 우리를 약간 조롱했음
  • 의존성이 아예 없는 날이 빨리 왔으면 좋겠음
    극단적인 예로, 요즘 딸을 위한 인터랙티브 교육 앱을 만들 때는 Opus에게 순수 JavaScript와 HTML만 쓰게 함
    이중 진자부터 유체 시뮬레이션까지 한 번에 잘 동작하고, 예전에는 의존성이 수백 개였음
    MIT 라이선스 코드라면 Opus에게 필요한 부분만 정확히 추출해서 내 용도에 맞게 수정해 포함시키라고 할 수 있음
    취미 프로젝트에서는 지금까지 잘 됐고, 앞으로는 프로덕션 소프트웨어도 의존성이 없어지면 좋겠음

    • 그렇게 하면 모든 변화와 수많은 예외를 전부 직접 관리해야 함
      Chrome이 어떤 API 형태를 바꾸면 직접 찾아서 고쳐야 하고, 모로코가 일광절약시간 시작 시점을 바꾸면 날짜/시간 처리 코드도 직접 업데이트해야 함
      이런 것들은 라이브러리가 대신 처리해주기 때문에 당연하게 여겨왔던 부분임
      딸이 다음 주면 관심을 잃을 이중 진자 시뮬레이터에는 큰일이 아니지만, 앞으로 무기한 동작해야 하는 걸 만드는 회사라면 문제가 됨
    • 이제 진짜 의존성인 브라우저에 노출된 셈임
    • 물론 Opus가 만들어낸 코드의 모든 줄을 오픈소스 유지보수자에게 기대하는 수준으로 꼼꼼히 검토할 거지? 그렇지?
      MIT 라이선스 원격 접근 코드를 하나 공개해서 Opus 학습 데이터에 들어가게 해봐야겠음
    • Rust를 Go보다 좋아해서 고민됨. LLM 관점에서도 Rust가 더 낫지만, Rust의 의존성 철학은 사실상 보안 블랙홀이고 Go가 훨씬 나음
    • 공유 가능한 저장소나 포지에 올려둔 게 있나? 농장 동물 철자 맞히기 게임이 있어서 내 라이브러리를 확장하고 아이디어를 더 만들고 싶음
  • Fast.AI 딥러닝 과정을 들을 때, 머신러닝 프로젝트가 끌고 오는 Python 의존성 수에 놀랐음
    웹 프런트엔드 프로젝트는 항상 서드파티 의존성이 많다고 여겨졌지만, 내게는 머신러닝 생태계가 훨씬 더 얽혀 보임
    게다가 웹 개발은 보안에 민감하다고 여겨져 오랫동안 보안 관련 지혜와 관행이 쌓였지만, 머신러닝 개발은 훨씬 임시방편적이고 일반적인 소프트웨어 공학 관행도 많이 적용되지 않는 듯함
    예를 들어 당시 머신러닝 모델 배포 방식 중 하나가 Python pickle이었는데, 이는 기본 제한이 없는 실행 가능한 객체임
    이 형식의 모델은 가져오는 컴퓨터에서 무엇이든 할 수 있었고, 이런 초기 무법지대 생태계는 보안 침해와 공급망 공격을 더 쉽게 만들 수 있음

    • 그 생태계에는 원래 소프트웨어 엔지니어가 아닌 사람이 많음
      일부는 하다가 코딩을 조금 배웠고, 일부는 수학자이며, 일부는 AI에 취한 개발자 같은 경우도 있음
      “코드는 이제 중요하지 않고, 돌아가면 된다”는 사고방식도 있음
      많은 사람에게 제대로 된 의존성 관리는 신경 쓰고 싶지 않은 잡일일 뿐임
      여러 머신러닝 프로젝트에서 이런 요소들이 합쳐지는데, 사실 머신러닝 프로젝트야말로 재현성에 가장 집중해야 하는 분야 중 하나임
  • 저장소 검색을 해보니 지난 하루 동안 생성된 저장소 중 "A Mini Shai-Hulud has Appeared" 텍스트가 들어간 저장소가 2.2천 개 나옴: https://github.com/search?q=A%20Mini%20Shai-Hulud%20has%20Ap...

    • 저장소 이름이 모두 dune의 두 용어/단어, 예를 들면 harkonen, mentat, ornithoptor 같은 것에 숫자가 붙은 형태로 보임
      이는 계정, 아마도 GitHub 인증/Actions 토큰이 침해된 뒤 저장소 생성에 사용됐다는 신호로 보임
    • https://github.com/tinin46 이 계정은 키를 많이 저장해둔 것처럼 보이는데, 용도는 잘 모르겠음
    • GitHub가 왜 바로 대응해서 README가 정규식에 맞는 저장소를 차단하지 못하는지 모르겠음
      지난번에도 이런 일이 있었으니 교훈을 얻었을 줄 알았음
      이 악성코드는 별로 노력도 하지 않았고, Microsoft도 별로 노력하지 않는 듯함
    • 이게 대체 무슨 일임?
  • 면책하자면 pytorch를 써본 적도 없고 소프트웨어 보안 관행도 잘 모름
    하지만 pytorch에 네트워크 접근이 필요한 시나리오가 잘 떠오르지 않음
    코드베이스 어디서든 아무 모듈이나 가져와 그 API를 쓸 수 있는 건 잘못된 것 같음
    추가적인 import 제한이나 정적 분석이 필요해 보임
    언어가 이런 문제를 다룰 올바른 추상화를 갖고 있지 않은 듯함
    비교하자면 Rust에서는 함수 시그니처만 보고도 내부 코드를 이해하지 않고 가변성과 수명을 볼 수 있는 점이 좋음
    의존성에도 비슷한 게 필요하다고 느낌
    개발자가 하위 코드를 들여다보지 않고도 모든 의존성을 쉽게 감사해서 “아, 이 의존성은 eval()을 쓰네” 또는 “네트워크 접근을 하네”라고 볼 수 있어야 함
    모바일 앱은 권한을 강제하는데, 개발자도 특정 기능만 허용 목록에 넣고 온갖 기능을 통째로 받아들이지 않을 수 있어야 하지 않나 싶음

    • Python 생태계는 이런 걸 절대 허용하지 않겠지만, 이 주제가 그 안에서 더 잘 이해되고 인정받았으면 좋겠음
      일반화하기는 싫지만, 특히 AI 개발 커뮤니티는 다른 모든 고려보다 편의성을 선호하는 듯함
      예를 들어 프로젝트가 첫 실행 시 큰 모델을 자동 다운로드하는 게 표준처럼 되어 있음
      대개 비활성화할 수는 있지만, 여러 라이브러리에 걸친 코드 클래스의 깊은 계층 때문에 올바른 매개변수를 찾기가 정말 고통스러움
      복잡한 것들, 대개는 장난감에 가까운 것들을 너무 쉽게 시작할 수 있는 건 좋지만, 이 허용적인 분위기는 꽤 불편함
      첫 문제 해결 단계가 항상 “pip install …”인 것 같고, 일부 환경, 예를 들어 MacOS는 GPU 접근 가상화도 잘 되지 않음
    • 여러 컴퓨트 노드에 걸쳐 모델을 학습하는 경우가 있음. 그건 네트워크 접근이 필요한 큰 사례임
  • 이번 주에 Python 버전 관리를 위해 uv를 쓰는 게 좋은 생각인지 궁금했음
    웹사이트 [1]에는 “Python은 공식 배포용 바이너리를 제공하지 않으므로 uv는 Astral python-build-standalone 프로젝트의 배포판을 사용한다”고 되어 있음
    이 GitHub 저장소 https://github.com/astral-sh/python-build-standalone를 가리키고, 거기서는 또 https://gregoryszorc.com/docs/python-build-standalone/main/r...를 언급함
    내가 제대로 이해했다면 Python 빌드용 소스 코드를 python.org에서 직접 가져오지 않는 것 같은데, 이게 얼마나 안전한지 확신이 안 듦
    asdf [2]에도 같은 우려가 있지만, asdf는 pyenv [3]를 쓰고 그쪽이 더 공식에 가까운 느낌임
    Python 설치에는 uv와 asdf 중 어느 도구가 더 낫고 더 안전한지 누가 설명해줄 수 있나?
    [1] https://docs.astral.sh/uv/guides/install-python/
    [2] https://github.com/asdf-community/asdf-python
    [3] https://github.com/pyenv/pyenv/tree/master/plugins/python-bu...

    • python-build-standalone은 CPython 소스를 python.org에서 직접 가져옴[1]
      애초에 다른 어디서 가져오겠나 싶음
      [1]: https://github.com/astral-sh/python-build-standalone/blob/a2...
    • uvcpython은 별로 걱정하지 않음. 프로세스가 견고하고, 대응도 빠르며, 이제 자금도 상당함
      걱정되는 건 예를 들어 mdformat처럼 널리 쓰이지만 주로 한 사람이 여가 시간에 관리하는 포매터나, 몇 년째 업데이트되지 않았고 의존성 트리 3단계 아래에 있는 아주 특정한 의존성임
      활발히 개발 중인 앱에서 모든 업데이트를 고정하고 수동 승인하고 싶지는 않지만, 진지한 앱이라면 이제 그게 필수처럼 보이기 시작함
      그동안 암호화되지 않은 .env 파일에서 API 키를 꺼내야겠음
      대규모 소비자용 웹앱에서 당하면 창피하지만 이해는 되는데, 같은 호스트와 시스템에 우연히 있는 장난감 데모 저장소의 간접 의존성 때문에 수백~수천 달러를 잃는 건 너무 아픔
      이런 식으로 키를 도난당하면 OAI나 Anthropic이 환불해 주는지 아는 사람 있나? 아니면 사용자 실수인가?
    • 애초에 uv는 컴퓨터에서 실행해서 Python 바이너리, 패키지, 그 안의 바이너리, 시스템 전역 도구 등을 관리하는 바이너리
      Python 바이너리를 그들이 빌드하든 다른 누군가가 빌드하든 위험이 얼마나 달라지는지 모르겠음
  • 요즘 내 pip install의 대부분은 Claude Code가 제안하고 내가 그냥 Enter를 누르면서 생김
    모델은 몇 달 전 데이터로 학습됐으니 이번 주에 뭐가 침해됐는지 알 리가 없음
    “이 패키지가 지금 안전한가”를 판단하는 데 최악의 필터를 만든 셈임

    • 게으름과 실사 부족을 LLM 탓으로 돌리지 말아야 함
    • 무슨 필터를 말하는 건가?
      Claude Code가 인터넷에서 설치할 소프트웨어를 추천하게 하고, 그걸 그대로 설치한다고 한 것임
      Claude Code나 어떤 LLM도 “이 패키지가 지금 안전한가”를 판단하는 필터라고 제안하는 건 들어본 적이 없고, 말한 이유를 포함해 매우 나쁜 휴리스틱으로 보임
    • 오래된 학습 데이터도 일부 원인이지만, 최신 모델이라도 setup.py가 내 머신에서 무엇을 실행할지 알 수는 없음
      실행 전에 패키지를 실제로 검사하는 게 없기 때문임
      필요한 건 실행 전에 메타데이터를 가져와 어떤 훅이 있는지 확인하는 도구임
    • Enter를 누르지 않으면 쉽게 우회할 수 있음
    • “최악의 필터”라는 게 Claude가 시키는 대로 Enter를 누르는 걸 말하는 건가?
  • Claude Code는 거의 매일, 때로는 하루에 여러 번 업데이트됨
    언젠가 Anthropic이 침해되면 우리 모두 크게 당할 것임

    • “우리”가 누구를 말하는 건가?
    • 권한 없는 VM/컨테이너에서 제한된 네트워크 접근으로 실행한다면 그렇지 않음
      하지만 요즘은 모든 게 YOLO임
    • 이미 Polymarket 가격에 반영돼 있을 것 같음
  • GitHub에서 4월 20일에 올라온 이 메시지를 봤는데 좀 혼란스러움
    "deependujha hi @thebaptiste, thanks for inquiring. Release of 2.6.2 is blocked due to some internal reasons. Will notify once release is made."
    그때부터 문제를 알고도 지금까지 경고하지 않은 거라면 정말 싫을 것 같음
    더 아는 사람이 명확히 설명해주면 좋겠음
    https://github.com/Lightning-AI/pytorch-lightning/issues/216...

    • Lightning의 Andy임. 악성 패키지는 오늘 UTC 12:45 PM에 PyPI에 게시됐음
      그 전에는 영향받은 배포물이 없었고, 유출도 알지 못했음
      GitHub의 원래 릴리스에는 문제가 없었지만 혼란을 막기 위해 내려둔 상태임
    • uv를 쓰는 사람들을 위해: https://docs.astral.sh/uv/reference/settings/#exclude-newer