AI 기능이 활성화된 GitHub Actions는 단 하나의 댓글만으로도 탈취될 수 있으며, 이로 인해 API 키, 클라우드 토큰 및 기타 비밀 정보(secrets)가 유출될 수 있습니다. 한 보안 연구원은 공개 트리거, "skip prompts" 플래그와 함께 실행되는 AI 도구, 그리고 노출된 비밀 정보가 결합되어 데이터 유출로 이어지는 직관적인 경로가 존재하는 22개의 오픈 소스 저장소를 발견했습니다.

취약점 작동 방식

현재 많은 프로젝트가 Claude Code, GitHub Copilot CLI 및 이와 유사한 도구와 같은 AI 에이전트를 CI 파이프라인에 직접 내장하고 있습니다. 워크플로 단계에서 셸 명령을 실행할 때, 도구가 대화형 권한 요청을 무시하도록 하는 플래그를 추가하는 경우가 많습니다. 이슈, 댓글 또는 풀 리퀘스트(pull-request) 제목과 같은 공개적인 입력값으로 워크플로가 시작되면, 공격자는 AI가 명령어로 처리할 텍스트 한 줄만 게시하면 됩니다.

“skip prompts” 플래그로 인해 이미 제한 없는 셸 액세스 권한을 부여받은 AI는 워크플로가 노출하는 모든 환경 변수나 파일을 읽을 수 있습니다. 만약 해당 작업(job)에서 API 키, 클라우드 서비스 토큰 또는 전체 서비스 계정 자격 증명과 같은 비밀 정보를 로드한다면, AI는 해당 값을 공격자가 제어하는 서버로 전송(pipe)할 수 있습니다. 코드 변경이나 새로운 의존성 추가 없이, 그저 무해해 보이는 댓글 하나만으로 가능합니다.

실제 사례

연구원은 이미 패치가 완료된 세 개의 취약한 저장소를 확인했습니다.

  • pymc-labs/pymc-marketing – 프롬프트 인젝션을 통해 공개 이슈를 이용하여 Anthropic API 키에 접근할 수 있었습니다.
  • MadAppGang/dingo – 워크플로가 Claude Code에 전체 Bash 액세스 권한을 부여했으며, 동일한 작업 내에서 두 개의 비밀 정보를 노출했습니다.
  • MadAppGang/claudish – dingo 프로젝트와 동일한 취약한 템플릿을 재사용했습니다.

한 사례에서는 실제 사용 중인 클라우드 서비스 계정 키가 발견되었으며, 연구원은 이를 주요 AI 제공업체의 보안 팀에 직접 보고했습니다. 현재 유지 관리자들에게 12건의 추가 보고가 전달된 상태이며, 수정 사항이 적용될 때까지 해당 이름은 공개되지 않습니다.

위험 요소

공격자가 비밀 정보를 추출하면 그 피해는 즉각적이고 막대할 수 있습니다. 클라우드 서비스 계정 키는 컴퓨팅 리소스, 스토리지 버킷 및 기타 유료 서비스에 대한 제한 없는 액세스 권한을 부여합니다. 대규모 언어 모델(LLM) 제공업체의 API 키는 무제한 쿼리를 실행하여 잠재적으로 수천 달러의 비용을 발생시킬 수 있습니다. 또한, 이 익스플로잇은 CI 환경 내부에서 실행되므로 침해 사고가 다운스트림으로 확산될 수 있습니다. 즉, 침해된 러너(runner)에서 빌드된 모든 아티팩트에 악성 코드가 포함될 수 있어, 단일 저장소가 공급망 공격 벡터로 변질될 수 있습니다.

AI 지원 CI에 의존하는 팀에게 이는 매우 극명한 트레이드오프입니다. 자동 생성된 코드, 린팅(linting) 또는 문서화의 편리함은 공개 댓글이 은밀한 백도어가 될 수 있는 위험과 저울질되어야 합니다.

취약점을 놓치기 쉬운 이유

연구원은 처음에 6건의 보고서를 제출했으나 나중에 철회했습니다. 이러한 철회는 Action의 소스 코드를 한 줄씩 검토한 결과가 아니라, GitHub Actions의 권한 확인 방식에 대한 가정에서 비롯되었습니다. 문서와 직관은 오해를 불러일으킬 수 있습니다. AI 기능이 활성화된 단계의 보안 태세를 확인하는 유일하고 신뢰할 수 있는 방법은 도구를 실행하는 코드와 이를 연결하는 워크플로 YAML 파일을 직접 검사하는 것입니다.

완화 조치 체크리스트

GitHub Actions 워크플로 내에서 AI CLI 또는 유사한 도구를 실행한다면, 머지(merge)하기 전에 다음 두 가지 질문에 답해 보십시오.

  1. 누가 워크플로를 트리거할 수 있습니까? 트리거를 신뢰할 수 있는 이벤트(예: 보호된 브랜치로의 push)로 제한하거나, 외부 기여자가 시작한 실행에 대해서는 명시적인 승인을 요구하십시오. 추가적인 제어 장치 없이 on: issue_comment 또는 on: issues를 사용하는 것을 피하십시오.

  2. 동일한 작업(job)에 어떤 비밀 정보가 로드됩니까? 제한 없는 셸 액세스 권한을 가진 AI 에이전트를 실행하는 작업에 API 키, 클라우드 토큰 또는 서비스 계정 자격 증명을 절대 노출하지 마십시오. 비밀 정보가 많이 포함된 단계는 AI 도구를 호출하지 않는 격리된 작업(job)이나 러너(runner)로 분리하십시오.

추가적인 보안 강화 단계:

  • 권한 확인 프롬프트를 건너뛰는 플래그를 제거하여, AI 도구가 셸 명령을 실행하기 전에 반드시 명시적인 확인을 요청하도록 강제하십시오.
  • AI 도구가 읽을 수 있는 모든 환경 변수를 정제(sanitize)하거나 마스킹(redact)하는 단계를 추가하십시오.
  • 네트워크 송신(egress) 제어 기능이 있는 셀프 호스팅 러너(self-hosted runner)를 사용하여 임의의 엔드포인트로 데이터가 유출되는 것을 차단하십시오.

반론: CI에서 AI의 유용성

옹호론자들은 생산성 향상이 위험보다 더 크다고 주장합니다. 자동화된 코드 제안은 리뷰 시간을 단축하고, AI 기반 테스트는 버그를 조기에 발견하게 해줍니다. 하지만 동일한 편리함이 공격 표면을 확장하기도 합니다. 핵심은 AI를 포기하는 것이 아니라, 셸 수준의 권한을 가진 모든 도구를 잠재적인 공격 벡터로 취급하는 것입니다.

향후 주목할 점

이번 조사 결과는 AI 기능이 활성화된 Actions에 대해 더 엄격한 기본 권한을 설정해야 한다는 논의를 GitHub 보안 포럼에서 이미 불러일으켰습니다. 향후 플랫폼 업데이트에는 다음과 같은 사항이 포함될 수 있습니다:

  • 직접적인 셸(shell) 액세스 없이 AI 도구가 샌드박스 환경에서 실행되도록 강제하는 플래그.
  • 이슈 본문이나 댓글 내 프롬프트 인젝션(prompt-injection) 패턴에 대한 내장 탐지 기능.
  • 워크플로가 공개 트리거와 비밀 정보(secret)가 포함된 작업을 혼합하여 사용할 때 발생하는 자동 알림.

현재로서는 저장소 관리자의 책임이 큽니다. 확인된 22개의 저장소는 이 문제가 단발적인 것이 아님을 보여줍니다. 동일한 워크플로 패턴을 사용하는 모든 프로젝트가 취약합니다. 공격자가 문제를 발견하기 전에 CI 설정을 신속히 감사하면 문제를 찾아낼 수 있습니다.

결론: 공개된 GitHub 이슈의 텍스트 한 줄만으로도 AI 에이전트가 CI 환경에 대한 완전한 제어권을 갖고 저장된 비밀 정보를 탈취할 수 있습니다. 워크플로를 실행할 수 있는 사용자를 확인하고, AI 기반 단계에서 비밀 정보가 사용되지 않도록 분리하며, 검증되지 않은 권한을 부여하는 모든 플래그를 면밀히 검토하십시오. 보안 침해로 인한 비용은 철저한 검토에 드는 노력보다 훨씬 큽니다.