GitHub Actions는 함정이다
해커들이 지칠 정도로 빠른 속도로 패키지를 털고 있으며, 모든 사후 분석 보고서에는 어김없이 GitHub Actions가 등장합니다.
2월 말, hackerbot AI1가 하나의 프로젝트 릴리스 키를 가로챘습니다. 한 달이 채 지나기 전에 50여 개 프로젝트에 크리덴셜 스틸러가 심어졌고, 감염된 저장소마다 다음 저장소의 크리덴셜을 차례로 훔쳐 갔습니다.
이번 공급망 해킹 사태는 GitHub Actions의 함정에서 시작되었습니다. 단순하고 잘못된 기본값 하나, 그리고 5년째 제안만 된 채 방치된 수정안 때문이었습니다.
GitHub Actions와 그 여파

Trivy는 오픈소스 보안 스캐너입니다. 하지만 3월 말에 Trivy를 사용하셨다면 끔찍한 일을 겪으셨을 것입니다.
3월 19일, 해커들은 실행되는 모든 곳에서 시크릿을 빼돌리려는 Trivy 버전을 배포했습니다. Trivy 측은 지속적 통합(CI) 시스템인 GitHub Actions의 “설정 오류” 때문이라고 밝혔습니다.
하지만 이 익스플로잇은 설정 오류라기보다는 GitHub Actions의 함정에 가까웠습니다.
Trivy가 어떻게 탈취당했는지 간소화한 예시는 다음과 같습니다2:
# INSECURE. DO NOT USE.
on:
pull_request_target
jobs:
check:
steps:
- uses: action/checkout@deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: ./.github/actions/setup-go
- uses: some/go-static-analysis@c0ffeec0ffeec0ffeec0ffeec0ffeec0ff언뜻 보면 이 코드는 문제가 없어 보입니다:
- 시크릿을 직접 참조하지 않습니다.
- 서드파티 액션이 불변 해시로 고정되어 있습니다.
- 풀 리퀘스트를 체크아웃해 정적 분석을 수행합니다.
하지만 이 코드는 2021년 GitHub 블로그 게시물 “pwn 요청 방지”에 나온 안티패턴을 그대로 옮긴 것입니다:
만약
pull_request_target워크플로가 […] 신뢰할 수 없는 코드만 실행하고 시크릿을 참조하지 않는다면, 그래도 취약합니까?그렇습니다
문제는 pull_request_target에 있습니다:
pull_request_target– 환경에 탐나는GITHUB_TOKEN을 그대로 넣어 줍니다.actions/checkout– 선택적 매개변수persist-credentials를 제공하며,false로 설정하면 시크릿을 제거합니다. 하지만 이 매개변수의 기본값은true입니다.
persist-credentials 매개변수를 false로 설정하는 문제는 GitHub Actions에서 2021년부터 열린 이슈로 남아 있습니다.
당신의 $HOME은 범죄 현장입니다
해커들은 Trivy의 키를 손에 넣자마자 더 많은 키를 훔치기 위해 Trivy의 새 버전을 배포했습니다.
LiteLLM은 CI에서 Trivy를 사용하고 있었습니다. 바로 그 CI로 코드를 Python 소프트웨어 저장소인 PyPI에 배포하고 있었습니다. LiteLLM의 CI가 오염된 Trivy를 실행했을 때, 해커들은 배포 키를 가로챘습니다.
그리고 3월 24일, Callum McMahon이 IDE를 켰을 때 MacBook이 멈춰 버렸습니다. 그렇게 그는 LiteLLM 탈취 사건을 발견하게 되었습니다.
McMahon의 MacBook은 해커들이 LiteLLM에 몰래 심어 둔 악성 코드 때문에 버벅이고 있었습니다. 그 악성 코드는 다음과 같은 크리덴셜을 훔치려 했습니다:
~/.netrc~/.aws/credentials~/.config/gcloud~/.config/gh~/.azure~/.docker/config.json~/.npmrc~/.git-credentials~/.kube/
이런 파일들은 보통 $HOME 디렉터리에 흩어져 있으며, 토큰과 키로 가득하고 대개 암호화되어 있지 않습니다.
AI와 공급망 파멸의 소용돌이
암호화되지 않은 크리덴셜, 고정되지 않은 의존성, CI의 자해적 설정 같은 문제는 예전부터 계속 겪어 온 일입니다.
하지만 AI는 모든 것을 가속했고, 보안 실수를 반복하는 속도까지 빨라졌습니다.
Trivy가 침해된 당일, 저는 Claude에게 “Docker 레지스트리 이미지를 보안 취약점에 대해 어떻게 스캔하나요?”라고 물었습니다.
답변의 일부는 다음과 같았습니다:
CI/CD Integration Example (GitHub Actions with Trivy)
- name: Scan image for vulnerabilities
uses: aquasecurity/trivy-action@master두 가지 면에서 잘못되었습니다:
- 고정되지 않은 참조 –
master는 수시로 바뀌는 참조입니다. 해커가 저장소를 좀비화하면 제가 첫 번째 피해자가 됩니다. - 현존하는 취약점 – 당일 게시된 CVE에 대해서는 전혀 언급이 없었습니다. 제가 묻지 않았으니 Claude도 확인하지 않은 것입니다.
한편 Vercel의 CEO는 최근 자사 데이터 유출의 원인을 “AI로 가속된” 해커 탓으로 돌렸습니다. 그리고 Anthropic은 최근 홍보 투어에서 자사의 프론티어 모델이 찾아낸 취약점에 대해 미국 연방준비제도 의장에게 브리핑하는 자리를 갖기도 했습니다.
LLM을 손에 쥔 공격자는 초능력을 얻습니다. LLM을 쓰는 방어자는 2010년대 중반의 CI 문제에 그대로 당합니다.
그리고 OpenBSD에서 27년 된 보안 문제를 찾아낼 수 있는 바로 그 도구가, GitHub Actions는 @master에 고정하라고 알려 줍니다.
어쨌든 스스로를
hackerbot-claw라고 칭하는 누군가일 수도 있습니다.↩︎제 GitHub Actions 예시는 aquasecurity/trivy #10259에서 제거된 액션을 더 단순화한 버전입니다.↩︎
글을 무작위로 읽기