Copilot Autofix가 연 Snowflake Jira…5일 만에 자격증명 탈취 실증

AI가 만든 보안 회귀를 다른 AI가 5일 만에 찾아 실제 자격증명 탈취까지 재현했다. Wiz Research의 공개 보고서에 따르면 GitHub Copilot Autofix가 공동 작성한 Snowflake 공개 저장소의 변경은 안전한 입력 처리 방식을 없애고, 공격자가 조작할 수 있는 이슈 제목을 셸 스크립트에 직접 넣었다. 인증하지 않은 GitHub 사용자도 특수한 제목의 이슈 하나로 GitHub Actions 실행기에서 임의 명령을 실행할 수 있는 구조였다.

문제는 snowflakedb/snowflake-connector-net 저장소의 jira_issue.yml 워크플로에서 시작됐다. 2026년 6월 18일 반영된 PR #1218은 이슈 제목을 env 변수로 전달하고 jq --arg로 JSON을 만들던 기존 패턴을 제거했다. 대신 ${{ github.event.issue.title }} 값을 run: 블록 안에서 직접 확장했다. 따옴표를 정리하는 sed 명령은 GitHub 템플릿 확장 뒤에 실행되므로, 공격자가 넣은 작은따옴표가 먼저 셸 문자열을 끝내 명령 주입 통로를 열었다.

보호 장치처럼 보이던 조건문도 작동하지 않았다. 워크플로는 새 이슈가 열릴 때 실행됐지만, 조건은 이슈 이벤트에 존재하지 않는 github.event.pull_request 값을 검사했다. 이 값은 항상 null이어서 모든 GitHub 사용자가 검사를 통과했다. 공개 저장소의 입력과 내부 시스템용 비밀 값이 같은 자동화 경로에서 만난 셈이다.

Wiz Red Agent는 Snowflake의 GitHub 조직을 훑어 이 패턴을 찾은 뒤 공격 가능성을 스스로 검증했다. 첫 페이로드가 Bash 구문 오류를 내자 오류를 분석해 셸 블록을 정상적으로 닫는 방식으로 수정했고, GitHub Actions 실행기에서 외부 콜백을 받았다. 유출된 토큰은 qa@snowflake.net 계정으로 인증됐으며 Snowflake의 엔지니어링, 보안 규정 준수, 버그 바운티 프로젝트를 포함한 내부 Jira에 읽기 접근을 허용했다. 발견부터 악용 검증, 영향 범위 평가까지 사람의 개입 없이 진행됐다는 것이 Wiz의 설명이다.

취약점은 6월 23일 HackerOne을 통해 전달됐고 Snowflake는 같은 날 안전한 env와 jq --arg 패턴을 복원했다. Jira 토큰은 다음 날 교체됐다. Snowflake는 5일의 노출 기간에 대한 감사 로그를 조사한 결과 Wiz의 시험 IP 외에 제3자가 접근한 증거는 없다고 밝혔다. Wiz도 개념 증명 과정에서 읽은 데이터를 모두 삭제했다고 확인했다.

이번 사례의 쟁점은 Copilot의 실수 하나보다 검토 체계의 빈틈이다. 과거에 보안 이유로 선택한 코드 패턴을 AI 도구가 평범한 정리 대상으로 판단하면, 겉보기에는 단순한 자동 수정이 권한 경계를 지울 수 있다. AI가 작성한 PR에도 사람의 코드와 같은 정적 분석과 보안 심사가 필요하며, 구조화된 파서를 직접 문자열 확장으로 바꾸는 변경은 자동으로 막을 필요가 있다. 공격 측 에이전트가 발견 시간을 시간 단위로 줄이는 만큼, 짧은 수명의 자격증명과 빠른 폐기 절차도 선택이 아니라 기본 조건이 되고 있다.