CI/CD 보안
이그레스 정책으로 GitHub Actions의 데이터 유출 막기
CI 작업은 시크릿을 보유하고, 1분 전에 내려받은 코드를 실행합니다. 액션, 패키지, 그리고 그 설치 스크립트입니다. 그중 하나라도 악성이라면, 시크릿을 훔치는 가장 쉬운 방법은 서버로 보내는 것입니다. 이그레스 정책은 작업이 어떤 서버에 접근할 수 있는지 정하고, 나머지는 차단합니다.
업데이트
시크릿이 CI 작업에서 빠져나가는 경로
작업은 리포지토리 토큰, 작업에 전달된 시크릿, 그리고 작업이 위임받는 클라우드 자격 증명에 접근할 수 있습니다. 작업에서 실행되는 코드는 이를 읽을 수 있습니다. 그리고 몇 가지 방법으로 밖으로 빼낼 수 있습니다.
- 네트워크를 통해. 공격자가 제어하는 서버로 요청을 보냅니다. 이그레스 정책이 막는 경로가 바로 이것입니다.
- 로그를 통해. 시크릿을 대개 인코딩해 작업 로그에 출력합니다. 2025년 3월, CISA는 침해된 tj-actions/changed-files 액션이 이 방식으로 시크릿을 노출했다고 보고했습니다.
- 출력물을 통해. 작업의 토큰으로 푸시한 아티팩트, 캐시, 커밋입니다.
그 코드가 꼭 악성 패키지일 필요는 없습니다. 워크플로 안의 AI 에이전트가 이슈나 풀 리퀘스트에 숨겨진 프롬프트 인젝션에 넘어가, 같은 경로를 사용할 수 있습니다.
이그레스 정책이 하는 일
대부분의 작업은 패키지 레지스트리, 컨테이너 레지스트리, 소스 호스트, 몇 가지 서비스 등 짧은 목적지 목록에만 접근하면 됩니다. 이그레스 정책은 그 목록을 허용하고 나머지는 모두 차단합니다. 기본 거부 정책에서는 알 수 없는 호스트로의 요청이 실패하고, 시크릿은 작업 안에 남습니다.
모든 문을 닫아 주지는 않습니다.
- 시크릿이 로그에 출력되는 것은 막지 못합니다. 로그를 비공개로 유지하고 액션을 커밋 SHA로 고정하세요.
- 허용한 목적지로도 데이터가 나갈 수 있으므로, 허용 목록은 좁게 유지하세요.
- 어떤 패키지가 악성이었는지는 알려 주지 않습니다. 그것은 패키지 검사와 SBOM의 몫입니다.
정책을 적용하는 세 가지 방법
- 러너의 에이전트. StepSecurity Harden-Runner는 작업의 첫 단계로 추가됩니다. 각 연결을 그 연결을 만든 단계에 매핑하고, 감사 모드에서 기준선을 만들며, 허용 목록에 없는 곳으로의 이그레스를 차단합니다.
- 정책이 내장된 러너. CRACI는 러너 자체로서 정책을 적용합니다. 다른 러너 제공업체도 네트워크 통제를 제공합니다. Depot의 Linux 러너에서의 이그레스 필터링, Namespace의 차단 또는 권고형 이그레스 정책 등이 그 예입니다.
- 자체 네트워크. 직접 구성하고 유지 관리하는 방화벽이나 프록시 뒤의 셀프 호스팅 러너입니다.
빌드를 깨지 않고 도입하기
- 관찰. 몇 번의 실행 동안 작업이 맺는 모든 연결을 기록합니다.
- 허용. 작업이 실제로 필요로 하는 것으로 허용 목록을 만듭니다.
- 차단. 기본 거부로 전환하고 위반을 지켜봅니다.
- 검토. 새 위반은 모두 누락된 소스 또는 보안 사고 중 하나로 다룹니다.
CRACI의 방식
CRACI에서 이그레스 정책은 러너의 일부입니다. 작업이 시작되기 전에 검증되고, 알 수 없는 필드는 거부되며, 실패 시 차단(fail closed)됩니다. 기본 제공 프리셋이 일반적인 패키지 소스를 다루고, 사용자 지정 소스와 연결로 나머지를 추가합니다. 작업 추적에는 모든 연결이 나열되며, 차단된 연결은 각각 이유와 함께 위반으로 표시됩니다. 프록시가 패키지를 인식하므로 같은 기록이 작업의 SBOM이 됩니다. API는 SBOM, 네트워크 추적, 출처 증명을 반환합니다.
CRACI에는 아직 전용 감사 모드가 없으며, 로드맵에 있습니다. 네트워크 정책이 없으면 작업의 트래픽은 허용되고 추적에 기록되므로, 정책을 적용하기 전에 정책에 무엇이 필요한지 확인할 수 있습니다. CRACI는 Linux에서 GitHub Actions 작업을 실행합니다. CI/CD 보안 도구 비교와 CRACI vs StepSecurity를 참조하세요.
CI의 이그레스 정책: 자주 묻는 질문
CI의 이그레스 정책이란 무엇입니까?
CI 작업이 맺을 수 있는 아웃바운드 네트워크 연결에 대한 규칙 집합입니다. 작업은 필요한 패키지 레지스트리와 서비스에 접근할 수 있고, 그 밖의 모든 목적지는 차단됩니다.
이그레스 정책이 있었다면 tj-actions 침해를 막을 수 있었을까요?
그것만으로는 막지 못했습니다. 이 사례에서 CISA는 시크릿이 외부 서버로 전송된 것이 아니라 워크플로 로그를 통해 노출되었다고 보고했습니다. 이그레스 정책은 네트워크 경로를 막고, 액션을 커밋 SHA로 고정하고 로그를 비공개로 유지하는 것은 로그 경로를 막습니다.
이그레스를 차단하면 빌드가 깨집니까?
정책이 빌드에 필요한 소스를 빠뜨리면 깨질 수 있습니다. 먼저 작업이 무엇에 연결하는지 기록하고, 그것을 바탕으로 허용 목록을 만든 다음 차단하세요. CRACI에서는 기본 제공 프리셋이 일반적인 패키지 소스를 다루며, 차단된 연결은 이유와 함께 작업 추적에 표시됩니다.
GitHub 호스팅 러너에서도 이그레스 정책을 쓸 수 있습니까?
예. StepSecurity Harden-Runner 같은 에이전트를 작업에 추가하면 됩니다. 또는 CRACI처럼 정책을 자체적으로 적용하는 러너로 작업을 옮길 수 있습니다.
작업 하나에 이그레스 정책을 적용해 보세요
워크플로 하나를 CRACI에서 실행하고, 작업이 맺은 모든 연결, 허용 목록에 필요한 호스트, 그리고 가져온 것의 SBOM을 확인하세요.
데모 예약