본문으로 건너뛰기
>_ITDITD웹 보안 플랫폼

사고 & 취약점

Codecov 유출 사고(2021) — CI 안의 '신뢰하던 도구'가 탈취되어 비밀 정보가 새어 나갔을 때

2021년 Codecov의 Bash Uploader(CI에서 실행되는 curl|bash 스크립트)가 상위(upstream)에서 변조되어 약 2개월간 고객의 CI 비밀 정보가 유출되었고, 체크섬 검사가 이를 발견했습니다. 공격 사슬을 방어 지도로 풀이하고, 가져온 산출물 검증·최소 권한 CI 비밀 정보·로테이션 같은 대책을 제시합니다.

게시 2026-06-07 업데이트 2026-06-07 7분 읽기

저희는 실제 공개 사고를 단순한 뉴스 재방송이 아니라 "이것을 어떻게 방어할 것인가"의 관점으로 읽습니다. 이 글은 공개 기록(공식 사후 분석, CISA, 보안 벤더 분석)에 근거하며, 출처는 글 끝에 명시합니다.

약 2개월
미탐지 기간
약 29,000
잠재적 영향 고객 수
SHA 검사
유일한 탐지 수단
downstream
HashiCorp/Twilio 등
사건 기록
대상
Codecov(코드 커버리지 도구)와 그 고객의 CI
공개
2021년 4월 15일(1월 31일부터 변조 / 4월 1일 탐지)
분류
공급망 공격(신뢰받던 산출물의 상위 변조) + CI 비밀 정보 탈취
규모
Codecov 고객 다수(최대 약 29,000곳). HashiCorp, Twilio, Rapid7에서 다운스트림 피해
근본 원인
CI가 가져온 산출물을 검증 없이 실행 + 벤더의 키 취급 + 과도하게 노출된 CI 비밀 정보
진짜 대책
가져온 산출물 검증, 최소 권한 CI 비밀 정보, 로테이션, 이그레스 모니터링

무슨 일이 있었나(쉽게 풀이)

많은 팀이 CI에서 curl … | bash처럼 외부 도구를 그대로 가져와 실행합니다. Codecov의 Bash Uploader가 바로 그런 스크립트였습니다.

공격자는 Codecov의 배포 과정에 있는 약점을 악용해 배포되는 스크립트 자체를 다시 작성했고, 그 스크립트가 CI에서 실행될 때 그 환경의 변수(비밀 정보)를 외부 서버로 전송하도록 만들었습니다. 고객 입장에서는 늘 하던 대로 신뢰하던 도구를 호출했을 뿐입니다. 여러분의 코드는 한 줄도 바뀌지 않았기 때문에 이상 신호가 거의 없습니다.

약 두 달 뒤, 한 고객이 스크립트의 체크섬(SHA256)을 공식 값과 비교해 불일치를 발견하면서 변조가 드러났습니다. 유출될 수 있었던 정보에는 클라우드 키, 배포 키, API 키, 토큰이 포함되었고, 거기서 공격은 HashiCorp, Twilio 같은 회사들의 다운스트림 유출로 연쇄되었습니다.

'여러분의 코드는 멀쩡하다'는 점 때문에 더 무섭다

공급망 공격은 여러분이 작성한 코드가 아니라 여러분이 신뢰하고 끌어오는 것을 노립니다. 그래서 코드 리뷰나 로그로는 좀처럼 잡히지 않습니다. "우리는 그것을 신뢰한다" = "우리는 그것을 검증하지 않는다"가 구멍이 됩니다.

사슬은 곧 방어 지도다

중요한 것은 이것이 4단계 사슬이었고 각 단계마다 멈출 수 있는 지점이 있었다는 점입니다. 공격 레시피가 아니라 "어디서 끊을 수 있었는가"로 읽어 주십시오.

① 신뢰하던 도구를 curl | bash로 실행(내용 미검증)

⊘ 멈춤: 가져온 산출물을 핀 고정 + 체크섬 검증 / 벤더링

② 산출물이 '상위(upstream)'에서 교체됨

여러분의 코드는 그대로이므로 알아챌 수 없다.

⊘ 멈춤: 정상으로 알려진 해시와 비교; 핀 고정된 버전 사용

③ CI 환경 변수(비밀 정보, 키, 토큰)가 외부로 전송됨

⊘ 멈춤: 단계별 최소 권한 CI 비밀 정보(모든 env를 넘기지 않음)

④ 탈취된 키가 프로덕션과 다른 서비스로 연쇄됨

⊘ 멈춤: 정기적인 키 로테이션 + 이그레스(아웃바운드) 모니터링

각 단계마다 '멈출' 수 있었다. 신뢰하는 것을 검증하고, 비밀 정보를 한정하고, 로테이션하고, 출구를 감시하라.

공개된 타임라인

  1. 2021-01-31

    Bash Uploader 변조가 시작됨(이후 간헐적으로 지속).
  2. 2021-03–

    고객의 CI에서 비밀 정보가 수 주에 걸쳐 알아채지 못한 채 새어 나감.
  3. 2021-04-01

    한 고객이 체크섬 불일치를 발견해 신고.
  4. 2021-04-15

    Codecov가 공개 발표. 고객에게 모든 비밀 정보 로테이션을 권고.
  5. 2021-04–

    HashiCorp, Twilio, Rapid7에서 다운스트림 영향이 드러남. Codecov는 이후 Bash Uploader를 폐기.

근본 원인은 하나의 실수가 아니다

이를 "Codecov 잘못"으로 치부하면 반복됩니다. 고객 쪽에서도 계층이 차례로 무너졌습니다.

당시의 상태

  • CI가 가져온 산출물을 검증 없이 실행(curl | bash를 신뢰)
  • CI 비밀 정보가 과도하게 노출(모든 단계가 모든 env 변수를 봄)
  • 비밀 정보를 거의 로테이션하지 않음(탈취된 키가 오래 유효)
  • CI 아웃바운드 트래픽 미감시

마땅히 그래야 할 상태(예방)

  • 가져온 산출물을 핀 고정 + 체크섬 검증하거나 직접 벤더링
  • CI 비밀 정보를 최소 권한으로, 필요한 단계에만 전달
  • 비밀 정보를 정기적으로 로테이션(유출되어도 수명이 짧음)
  • CI 이그레스를 모니터링하고 알 수 없는 목적지로의 전송을 탐지

'신뢰'는 검증과 짝을 이룬다

공급망 공격은 여러분이 신뢰하고 끌어오는 것 — 의존 라이브러리, CI 도구, 빌드 이미지 — 을 노립니다. XZ Utils 사례도 같은 형태였습니다. 신뢰를 최소화하고 끌어오는 것의 무결성을 기계로 검증하십시오.

여러분의 환경에서 막는 법

규모에 상관없이 작동하는, 우선순위 순서의 대책입니다. "여러분의 CI가 신뢰하고 실행하는 것"을 한 번 목록화하면 곧 자기 일이 됩니다.

1

가져온 산출물을 검증한다(curl|bash를 맹신하지 않기)

CI가 외부 스크립트나 바이너리를 가져온다면 핀 고정된 버전(태그/커밋) + 체크섬(SHA256) 검증을 요구하십시오. 가능하면 자신의 저장소로 벤더링하십시오. 이 사고는 바로 이 검사로 잡혔습니다.

2

CI 비밀 정보를 최소 권한으로 한정한다

모든 단계에 모든 env 변수를 넘기지 마십시오. 필요한 작업/단계에 필요한 비밀 정보만 전달하십시오. 단기 토큰(예: OIDC)을 사용해 저장된 장기 키를 줄이십시오.

3

비밀 정보를 정기적으로 로테이션한다

탈취되더라도 수명이 짧으면 피해가 제한됩니다. 로테이션을 일상화하고, 공급망 사고가 보고되면 즉시 로테이션하십시오.

4

CI 이그레스(아웃바운드 트래픽)를 모니터링한다

CI에서 알 수 없는 목적지로의 전송을 탐지할 수 있어야 합니다. 입구를 막지 못하더라도 유출을 알아채는 계층을 남겨 두십시오.

본 사이트의 태도: 신뢰를 최소화하고 검증한다

본 사이트는 의존성과 빌드 도입을 기계로 검증하도록 설계합니다. Codecov와 XZ Utils가 보여주는 것은 같은 사실입니다 — "우리는 신뢰한다"는 곧 "우리는 검증하지 않는다"가 되기 쉽고, 그것이 공급망 공격의 문이 됩니다. 신뢰를 줄이고 끌어오는 것의 무결성을 기계적으로 확인하십시오.

출처(공개 기록)

여기 담긴 사실은 다음 공개 정보에 근거하며, 방어적 교훈에 초점을 둡니다. 재현 절차나 변조된 코드는 다루지 않습니다.

  • Codecov, "Post-Mortem / Root Cause Analysis (April 2021)" — about.codecov.io
  • Codecov, "Bash Uploader Security Update" — about.codecov.io
  • CISA, "Codecov Releases New Detections for Supply Chain Compromise" (2021) — cisa.gov
  • Rapid7, "Analysis of the Codecov Supply Chain Compromise" (2021) — rapid7.com

이어서 읽기

FAQ

QCodecov 사고의 근본 원인은 무엇이었나요?
A

여러분 코드의 버그가 아니라, CI에서 실행하는 신뢰받던 외부 도구(Codecov의 Bash Uploader)가 출처(상위, upstream)에서 변조된 것입니다. CI가 curl로 스크립트를 가져와 내용을 검증하지 않고 실행했기 때문에 변조된 버전이 실행되었고, CI 환경 변수(비밀 정보)가 외부로 전송되었습니다.

Q왜 약 2개월간 알아채지 못했나요?
A

변조된 것이 남의 도구였기 때문입니다. 여러분의 저장소와 코드는 손대지 않았고, 로그에도 뚜렷한 이상이 나타나지 않습니다. 결국 한 고객이 스크립트의 체크섬(SHA256)을 공식 값과 비교해 불일치를 발견하면서 잡혔습니다.

Q소규모 프로젝트에도 해당되나요?
A

그렇습니다. 'curl … | bash'로 도구를 CI에 끌어오는 것은 1인 개발에서도 흔하며, 그것이 탈취되면 CI 비밀 정보가 한 번에 털립니다. 여기서 다루는 방어책(가져온 산출물을 핀 고정 + 체크섬 검증, 최소 권한 CI 비밀 정보, 정기 로테이션)은 어떤 규모에서도 작동합니다.