CI/CD에서 Intent-Verification 격차: 실제 공격에서 인증이 실패하는 이유
Source: Dev.to
If an action originates from a valid session token, it must originate from valid human intent.
유효한 세션 토큰에서 시작된 행동은 유효한 인간 의도에서 시작된 것으로 간주됩니다.
개요
현대 CI/CD 파이프라인은 겉보기에 단순한 가정 위에 구축됩니다:
If an action originates from a valid session token, it must originate from valid human intent.
유효한 세션 토큰에서 시작된 행동은 유효한 인간 의도에서 시작된 것으로 간주됩니다.
이 가정은 직관적으로 보입니다. 엔지니어는 SSO를 통해 인증받고 세션 토큰을 받으며, 그 토큰이 프로덕션 배포를 승인합니다. 토큰이 유효하고 사용자가 올바른 역할을 가지고 있다면 시스템은 진행됩니다.
SolarWinds, Codecov, 그리고 Log4j는 실제로 이 가정이 틀렸음을 보여주었습니다.
세 경우 모두 시스템은 인가 관점에서는 “정상적으로” 동작했습니다:
- 자격 증명이 유효함
- 토큰이 정당함
- 파이프라인이 설계대로 실행됨
그럼에도 불구하고 재앙적인 결과가 발생했습니다.
Intent‑Verification 격차
이 글에서는 제가 Intent‑Verification Gap이라고 부르는 개념을 소개합니다: 현대 CI/CD 보안 모델이 자격 증명의 소유와 의식적인 인간 의도를 구분하지 못하는 구조적 실패입니다. 이 격차는 이론적인 것이 아니라 실제 Advanced Persistent Threats (APTs)가 악용하는 공격 표면입니다.
확률적 신뢰 모델
대부분의 CI/CD 파이프라인은 확률적 신뢰 모델에 따라 동작합니다:
- 사용자가 어느 시점에 인증합니다.
- 세션 토큰이 몇 시간 동안 유지됩니다.
- 해당 기간 동안 수행된 행동은 지속적인 사용자 의도를 반영한다고 가정됩니다.
이 모델은 확률적입니다. 토큰 수명 동안 사용자가 자신의 디바이스, 네트워크, 실행 환경을 계속 제어하고 있다고 가정합니다. 현대 위협 모델은 이 가정을 깨뜨립니다.
악성코드가 엔드포인트를 장악하면, 시스템은 다음을 구분할 수 없습니다:
- 코드를 의도적으로 배포하는 인간
- 동일한 토큰을 사용해 악성 아티팩트를 배포하는 악성코드
파이프라인 관점에서는 두 경우를 구분할 수 없습니다: 서명이 유효하고, 역할이 올바르며, 인가 검사가 통과합니다. 이는 구현상의 버그가 아니라 신뢰 모델 자체의 결함입니다.
인증 vs. 의도
보안 용어에서는 다음과 같이 구분합니다:
| Concept | Question |
|---|---|
| Authentication (AuthN) | 당신은 누구입니까? |
| Authorization (AuthZ) | 당신은 이것을 할 권한이 있습니까? |
AuthN도 AuthZ도 세 번째, 더 중요한 질문에 답하지 못합니다:
사람이 이 특정 순간에 이 특정 행동을 의식적으로 수행하려는 의도가 있었습니까?
전형적인 파이프라인 흐름
- Identity Assertion – SSO / 토큰
- Privilege Check –
DEPLOY_PROD역할 - Execution – 프로덕션 변경
이 순서는 권한을 증명할 뿐, 의도를 증명하지는 못합니다. 악성코드가 캐시된 토큰을 사용해 배포를 실행한다면, 시스템은 “정상적으로” 동작하지만 보안 관점에서는 치명적인 실패를 초래합니다. 이것이 의도‑검증 격차(Intent‑Verification Gap)입니다.
실제 사례
SolarWinds Sunburst
종종 “빌드 시스템 침해”로 표현되지만, 근본적인 실패는 의도 검증이었습니다:
- 빌드 시스템이 악성 코드를 컴파일했습니다.
- 그것은 아티팩트에 서명했습니다.
- 고객에게 배포했습니다.
CI/CD 파이프라인 관점에서는 아무 문제도 없었습니다. 놓친 질문은 전혀 제기되지 않았습니다:
인간이 이 특정 아티팩트를 배포하려는 의도를 의식적으로 가졌는가?
빌드 서버가 침해되면 암호 서명은 무의미해집니다. 서버는 정품 코드를 서명하듯 악성 코드도 기꺼이 서명했습니다.
Codecov 침해
침해는 몇 달 동안 지속되었습니다. 이는 파이프라인에서 실제로 실행된 코드에 대한 불변의 포렌식 기록이 없었기 때문입니다. 파이프라인 관점에서는:
- 스크립트가 다운로드되었습니다.
- 환경 변수가 내보내졌습니다.
- 모든 것이 정상적으로 실행되었습니다.
변조 방지 기록이 없으면 다음 질문에 답할 수 없습니다:
- 어떤 행동이 승인되었는가?
- 언제 발생했는가?
- 실제로 어떤 코드가 실행되었는가?
포렌식 진실을 보존하지 못하는 보안 시스템은 침해 후 현실을 재구성할 수 없습니다.
더러운 노트북 가설
현대 개발자 워크스테이션은 적대적인 영역이다. 일반적인 노트북은 다음을 실행한다:
- 브라우저 확장 프로그램
- 백그라운드 데몬
- 패키지 매니저
- 채팅 클라이언트
- 빌드 도구
- 원격 접근 에이전트
이 중 어느 하나라도 손상될 수 있다. 그러나 대부분의 보안 시스템은 동일한 기계가 다음을 수행할 수 있다고 가정한다:
- 승인 UI 표시
- 암호화 서명 생성
- 의도를 안전하게 전달
더러운 노트북 가설: 개발에 사용되는 모든 범용 컴퓨팅 장치는 기본적으로 손상된 것으로 간주해야 한다.
승인과 서명이 개발과 동일한 장치에서 이루어질 경우, 악성코드는 사용자가 보는 화면을 조작하면서 실제로는 다른 작업에 서명하도록 할 수 있다—이로써 신뢰 경계가 무너진다.
프로세스‑기반 제어가 실패하는 이유
산업계가 공급망 공격에 대응하는 방식은 일반적으로 절차적입니다:
- 승인 절차 증가
- 정책 증가
- 준수 체크리스트 증가
- 교육 증가
이것들은 프로세스‑기반 제어입니다. 실행 환경 자체가 손상되면 실패합니다:
- 손상된 컴파일러는 동료 검토를 존중하지 않습니다.
- 손상된 빌드 서버는 관리자의 승인 절차를 따르지 않습니다.
물리 기반 보안 반론
보안은 공격자가 소프트웨어만으로는 우회할 수 없는 제약에 기반해야 합니다. 예시:
- 물리적 존재
- 하드웨어 격리 서명(예: HSM)
- 에어갭 승인 채널
- 불변 저장소(예: WORM 드라이브)
보안이 물리적 특성에 의존할 때, 공격자는 디지털 → 물리 도메인을 넘어야 하며, 이는 공격 비용을 크게 증가시킵니다.
토큰은 공백 수표와 같다
세션 토큰은 공백 수표처럼 동작합니다:
- 몇 시간 동안 유효합니다.
- 재생될 수 있습니다.
- 탈취될 수 있습니다.
- 악성코드에 의해 프록시될 수 있습니다.
토큰은 시간적 맥락을 무시하고, 고위험 행동을 저엔트로피 신호로 변환합니다. 이것이 토큰 기반 배포 권한 부여가 적대적인 엔드포인트 가정 하에 구조적으로 안전하지 않은 이유입니다.
배포는 이전 로그인 이벤트에서 물려받은 권한이 아니라 새로운 의도 증명을 요구해야 합니다.
초점 전환: 정체성에서 의도로
Modern DevSecOps는 집착적으로 다음에 답합니다:
이 사람은 누구인가?
하지만 침해된 환경에서는 정체성이 무의미합니다. 진정으로 중요한 것은:
이 사람이 이 사양을 의식적으로 승인했는가?
CI/CD 파이프라인에서 의도 검증
- Intent는 행동이며, 상태가 아니다.
- Identity는 상태이며, 행동이 아니다.
의도를 검증하지 않고 정체성만 인증하는 보안 시스템은 현대 CI/CD 파이프라인에서 가장 중요한 실패 모드에 대해 눈이 멀어 있다.
의도‑검증 격차
의도‑검증 격차를 수용하면 여러 아키텍처 요구사항이 뒤따른다:
- 승인은 세션이 아니라 개별 행동당 이루어져야 한다
- 서명은 개발 환경과 물리적으로 격리되어야 한다
- 인가(Authorization)는 특정 아티팩트와 환경에 암호학적으로 결합되어야 한다
- 로그는 설계상 불변이어야 한다
- 마찰은 위험에 비례해야 하며, 균일하지 않아야 한다
이러한 원칙들은 의도‑검증 아키텍처의 기반을 이룬다.
주요 시사점
- 정체성은 편의 계층이다.
- 의도는 보안 경계이다.
CI/CD 시스템이 인간의 의도를 일급 암호학 원시(primitives)로 다루지 않는 한, 공급망 공격은 모든 규정 준수 검사를 통과하면서도 제어를 우회할 것이다.
CI/CD 보안의 미래는 대시보드를 더 많이 만드는 것이 아니다.
그것은 신뢰 가정의 감소이다.