Trivy GitHub Actions 태그 대규모 침해: CI/CD 시크릿 탈취 공격
Trivy under attack again: Widespread GitHub Actions tag compromise secrets
TL;DR Highlight
Trivy의 공식 GitHub Action 태그 75개가 악성 코드로 교체되어 이를 참조하는 1만 개 이상의 CI/CD 파이프라인이 AWS/GCP/Azure 자격증명과 SSH 키를 탈취당할 위험에 노출되었다.
Who Should Read
GitHub Actions로 CI/CD 파이프라인을 운영 중이며 Trivy 같은 보안 스캐너를 사용하는 DevOps/백엔드 개발자. 특히 aquasecurity/trivy-action을 버전 태그로 참조하고 있는 팀이라면 즉시 확인해야 한다.
Core Mechanics
- 공격자가 aquasecurity/trivy-action 레포지토리의 76개 버전 태그 중 75개를 force-push로 악성 커밋으로 교체했다. @0.34.2, @0.33.0, @0.18.0 등 흔히 쓰는 태그가 모두 영향을 받았고, 현재 유일하게 안전한 태그는 @0.35.0뿐이다.
- 악성 페이로드는 GitHub Actions 러너 환경에서 실행되며, 러너 프로세스 메모리를 덤프해 시크릿을 추출하고, SSH 키를 수집하고, AWS/GCP/Azure 자격증명과 Kubernetes 서비스 어카운트 토큰을 외부로 유출한다.
- 이번 공격의 교묘한 점은 브랜치 push나 새 릴리즈 생성이 아닌 기존 태그의 force-push 방식을 사용했다는 것이다. 이 방법은 커밋 히스토리에 잘 남지 않고 알림도 트리거하지 않아 탐지가 어렵다.
- 공격의 근본 원인은 3월 초 OpenVSX VS Code 익스텐션 침해 사건 때 탈취된 CI/CD 자격증명이다. Trivy 팀이 시크릿을 교체했지만 교체 과정이 원자적(atomic)으로 이루어지지 않아, 공격자가 새로 발급된 토큰에도 접근권을 유지한 것으로 추정된다.
- GitHub에서 이 Action을 참조하는 워크플로우 파일이 10,000개 이상이며, 악성 코드는 정상적인 Trivy 스캔이 실행되기 전에 먼저 실행되어 사용자가 이상을 눈치채기 어렵게 설계됐다.
- Docker Hub에서도 추가 피해가 확인됐다. 3월 22일에 악성 Trivy 이미지 태그 0.69.4, 0.69.5, 0.69.6이 발견됐고, latest 태그도 노출 기간 동안 악성 이미지를 가리켰다.
- Socket의 AI 스캐너는 3월 20일 19:15 UTC부터 실시간으로 이 캠페인을 감지해 182개의 위협 피드 항목을 생성했고, 모두 Backdoor/Infostealer/Reconnaissance 악성코드로 정확히 분류했다.
- 이번 사건은 같은 달 3월에 발생한 Trivy 생태계의 두 번째 공급망 침해 사고다. 첫 번째 침해로 탈취된 자격증명이 완전히 무력화되지 않은 채로 두 번째 공격에 재활용됐다.
Evidence
- GitHub의 공식 보안 가이드라인은 Actions를 버전 태그가 아닌 전체 커밋 SHA로 고정(pin)하는 것을 권고하고 있다는 언급이 있었다. 이에 대해 'GitHub이 아예 Actions에 불변(immutable) 버전 정책을 강제하면 이 문제를 원천 차단할 수 있는데 왜 안 하냐'는 의견이 제기됐다.
- 자격증명 교체 과정의 구체적 실패 원인에 대해 커뮤니티 내 의문이 많았다. '3월 22일 두 번째 침해가 발생한 것을 보면 공격자가 두 번의 자격증명 교체를 뚫고 접근권을 유지한 것 같다'는 분석이 나왔고, GitHub의 다양한 토큰 종류(PAT, OAuth, GitHub App 토큰 등)에 따라 교체 절차가 다르기 때문에 어떤 유형의 자격증명이 문제였는지 불분명하다는 지적도 있었다.
- 보안 스캐너에 과도한 권한을 부여하는 관행에 대한 비판이 나왔다. 실제로 근무 중인 한 개발자는 '보안팀이 매달 새 스캐너를 도입하면서 전체 코드베이스나 클라우드 접근 권한을 요구하는데, 내가 요구사항의 10%라도 들어줬으면 이미 여러 번 털렸을 것'이라며 보안 도구 자체의 공급망 리스크를 경고했다.
- 이번 사고로 직접적인 피해를 입은 것으로 보이는 개발자가 '앞으로 몇 주 동안 수십 개의 보고서를 작성하고 수없이 많은 미팅을 해야 할 것 같다'며 실무 차원의 여파를 공유했다. Trivy가 두 번이나 침해당했다는 사실에 대한 좌절감도 표현했다.
- '항상 이런 도구들은 샌드박스 안에서 실행해서 피해 범위를 제한한다'는 실용적인 대응책을 공유한 댓글도 있었다. 또한 npm만 공급망 공격의 표적이 된다고 생각했던 사람들에게 경각심을 주는 사례라는 빈정섞인 지적도 있었다.
How to Apply
- aquasecurity/trivy-action을 버전 태그(@0.34.2 등)로 참조하고 있다면, 지금 당장 워크플로우 파일을 검토해야 한다. 태그 대신 신뢰할 수 있는 특정 커밋의 전체 SHA(예: uses: aquasecurity/trivy-action@커밋SHA)로 고정하면, 태그가 force-push로 교체되더라도 영향을 받지 않는다.
- 3월 20일 19:15 UTC 이후 aquasecurity/trivy-action을 사용한 워크플로우가 실행됐다면, 해당 파이프라인에서 사용된 모든 시크릿(AWS 키, GCP 서비스 어카운트, Azure 자격증명, SSH 키, Kubernetes 토큰 등)을 즉시 교체해야 한다. 단순 교체가 아니라 이전 자격증명으로 접근 가능한 리소스의 접근 로그도 감사(audit)해야 한다.
- CI/CD 파이프라인에서 보안 스캐너나 서드파티 Actions에 부여하는 권한을 최소화해야 한다. GitHub Actions의 GITHUB_TOKEN 권한을 워크플로우 레벨에서 read-only로 제한하고, 클라우드 자격증명은 OIDC(임시 토큰 방식)를 사용하면 탈취된 자격증명의 유효 시간을 단축할 수 있다.
- Socket, Dependabot, Renovate 같은 도구를 활용해 GitHub Actions 의존성을 모니터링하면, 이번처럼 태그가 악성 커밋으로 교체되는 것을 실시간으로 감지할 수 있다. Socket의 경우 이번 공격을 실시간으로 탐지해 Backdoor/Infostealer로 분류했다.
Code Example
# 취약한 방식: 버전 태그 참조 (force-push로 교체 가능)
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.34.2 # ❌ 위험
# 안전한 방식: 전체 커밋 SHA로 고정 (불변)
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@a20de5420d57c4102547773ee84a9575c8d547ea # ✅ 안전
# GitHub Actions 권한 최소화 설정 예시
permissions:
contents: read # 최소 권한만 부여
security-events: write # Trivy SARIF 업로드에 필요한 경우만
# OIDC를 사용한 AWS 임시 자격증명 (탈취 시 피해 최소화)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@커밋SHA
with:
role-to-assume: arn:aws:iam::ACCOUNT:role/ROLE
aws-region: ap-northeast-2
# access-key-id/secret-access-key 하드코딩 금지Terminology
관련 논문
LLM이 TLA+로 실제 시스템을 제대로 모델링할 수 있을까? — SysMoBench 벤치마크
LLM이 TLA+ 명세를 작성할 때 문법은 잘 통과하지만 실제 시스템과의 동작 일치도(conformance)는 46% 수준에 그친다는 걸 체계적으로 검증한 벤치마크 연구로, AI 기반 형식 검증의 현실적 한계를 보여준다.
Natural Language Autoencoders: Claude의 내부 활성화를 자연어 텍스트로 변환하는 기법
Anthropic이 LLM 내부의 숫자 벡터(활성화값)를 직접 읽을 수 있는 자연어로 변환하는 NLA 기법을 공개했다. AI가 실제로 무슨 생각을 하는지 해석하는 interpretability 연구의 새로운 진전이다.
ProgramBench: LLM이 프로그램을 처음부터 다시 만들 수 있을까?
LLM이 FFmpeg, SQLite, PHP 인터프리터 같은 실제 소프트웨어를 문서만 보고 처음부터 재구현할 수 있는지 측정하는 새 벤치마크로, 최고 모델도 전체 태스크의 3%만 95% 이상 통과하는 수준에 그쳤다.
MOSAIC-Bench:코딩 에이전트의 Compositional Vulnerability 유도 측정
티켓 3장으로 쪼개면 Claude/GPT도 보안 취약점 코드를 53~86% 확률로 그냥 짜준다.
LLM의 거절(Refusal) 동작은 단 하나의 방향(Direction)으로 제어된다
13개의 오픈소스 채팅 모델을 분석했더니, 모델이 유해한 요청을 거절하는 동작이 내부 활성화 공간에서 단 하나의 1차원 벡터 방향으로 인코딩되어 있었다. 이 방향을 제거하면 안전 파인튜닝이 사실상 무력화되므로, 현재 안전 학습 방식이 얼마나 취약한지 보여준다.
LLM의 구조화된 출력(Structured Output)을 테스트하는 새 벤치마크 SOB 공개
스키마 준수 여부만 보던 기존 벤치마크의 한계를 넘어, 실제 값의 정확도까지 7가지 지표로 평가하는 Structured Output Benchmark(SOB)가 공개됐다. 인보이스 파싱, 의료 기록 추출처럼 JSON 출력의 정확성이 중요한 프로덕션 시스템에서 어떤 모델을 써야 할지 판단하는 데 직접적으로 참고할 수 있다.