워크플로가 issues: opened
해당 커밋에는 “Copilot Autofix powered by AI”가 공동 작성자로 표시됐고, AI 보조 검토 과정에서도 문제가 발견되지 않았다. 다만 공개된 근거만으로 Copilot이 안전하지 않은 변경을 직접 생성했는지, 사람이 작성한 변경을 검토하다가 놓쳤는지는 확정할 수 없다. 따라서 가장 신중한 표현은 Copilot이 해당 변경과 연관돼 있었고 인젝션을 탐지하지 못했다는 것이다. 모델이 결함을 직접 작성했다고 단정할 근거는 부족하다.
Wiz의 Red Agent는 스노플레이크의 공개 GitHub 조직을 대상으로 위험한 CI/CD 패턴을 자동 분석했다. 그 과정에서 이슈처럼 신뢰할 수 없는 데이터가 셸 run: 블록에 들어가는 jira_issue.yml을 식별했고, 조작된 공개 이슈 제목만으로 GitHub 호스팅 Actions 러너에서 임의 명령 실행이 가능하다고 추론했다.
취약한 변경이 병합된 지 5일 후인 6월 23일, Red Agent는 스노플레이크의 HackerOne 취약점 신고 프로그램을 통해 조작된 이슈를 열었다. 이슈 제목은 셸 문자열의 경계를 벗어났고, 주입된 명령은 인증된 개념증명에 사용된 외부 콜백으로 Jira 인증정보를 전송했다.
이는 통제되지 않은 침입이 아니라 스노플레이크가 운영한 HackerOne 프로그램 안에서 수행된 승인된 보안 테스트였다. 그러나 보안상 취약점 자체는 분명했다. 공개 이슈 하나가 내부 인증정보를 다루는 워크플로 단계에 도달해, 단순한 이슈 생성 행위를 명령 실행으로 바꿀 수 있었기 때문이다.
침해된 워크플로에는 스노플레이크 내부 Jira 접속에 필요한 설정과 인증정보가 있었다. 여기에는 Jira 주소, 사용자 이메일, API 토큰이 포함됐으며, 회수된 토큰은 qa@snowflake.net 계정과 연결돼 있었다. Wiz는 이 토큰으로 내부 Jira 포털에 인증하고 잠재적인 노출 범위를 확인했다.
공개된 보도에 따르면 해당 토큰은 엔지니어링, 보안 컴플라이언스, 버그바운티 활동과 관련된 Jira 프로젝트에 대한 읽기 접근을 제공했다. 다만 토큰의 전체 권한 목록이나 접근 가능한 모든 기록이 공개된 것은 아니다. 따라서 확인 가능한 결론은 토큰이 민감한 내부 Jira 콘텐츠에 접근할 수 있는 권한을 제공했다는 수준이며, 스노플레이크 시스템 전반에 대한 무제한 접근을 의미하지는 않는다.
영향받은 자산은 저장소의 CI/CD 자동화였다. 결함이 애플리케이션 실행 코드가 아니라 GitHub Actions 워크플로에 있었기 때문에, 영향을 받은 Snowflake Connector for .NET 배포 버전은 보고되지 않았다.
현재까지 무단 제3자 접근은 보고되지 않았고, CVE가 부여됐다는 발표도 없었다. 영향을 받은 커넥터 릴리스 역시 확인되지 않았다. 이는 확인된 피해 범위를 제한하는 사실이지, 처음부터 워크플로 설계가 안전했다는 뜻은 아니다. 내부 인증정보를 처리하는 워크플로에서 공개 이슈 제목이 셸 명령의 일부가 되도록 허용해서는 안 된다.
이번 사례는 스노플레이크나 Copilot에만 국한되지 않는다. 이슈 제목, 풀 리퀘스트 제목, 브랜치명, 댓글처럼 GitHub 컨텍스트에서 들어오는 값이 셸 명령으로 넘어가는 순간 모두 공격자 입력으로 취급해야 한다.
실무에서 적용할 수 있는 기본 원칙은 다음과 같다.
run: 스크립트에 직접 보간하지 말고 환경변수로 전달한다.jq 같은 구조화된 도구를 사용한다.이번 사건은 AI를 둘러싼 새로운 보안 현실을 압축해서 보여준다. 한 AI 기반 코딩 시스템이 위험한 CI/CD 변경을 놓친 뒤, 또 다른 AI 기반 공격 에이전트가 며칠 안에 이를 찾아내고 실제 영향까지 검증했다. 자동화는 수정과 공격 모두를 빠르게 만들 수 있지만, 독립적인 보안 검토를 대신할 수는 없다.