보안
ZCode는 개발자의 Git 히스토리 전체를 묻지도 않고 업로드했다. Z.ai의 수정은 "이미 누가 읽었는지"를 말하지 않는다
Z.ai의 AI 코딩 에이전트는 작업 공간 전체를——전체 Git 히스토리를 포함해——암호화 아카이브로 묶어, 회사만 복호화할 수 있는 클라우드 버킷으로 조용히 보냈다. 대응은 빠르고 이례적으로 투명했지만, 이미 빠져나간 데이터의 행방만은 예외다.
MAI
9월 18일, 한 리버스 엔지니어링 보고서가 Z.ai——과거 즈푸AI(Zhipu AI)로 알려졌고 오픈웨이트 GLM 모델을 만든 중국 연구소——를 둘러싼 일주일간의 정밀 검증에 불을 붙였다. 대상은 모델이 아니었다. Z.ai의 AI 코딩 에이전트인 ZCode였고, 밝혀진 사실은 이 도구가 개발자의 작업 디렉터리——소스 코드, 설정, 그리고 완전한 Git 히스토리——를 암호화 아카이브로 묶어, 사용자가 무언가를 공유하기로 결정하기도 전에 클라우드 스토리지로 업로드하고 있었다는 것이다.
도구가 한 일
ZCode는 개발자의 편집기 안에서 실행되며, 코딩 보조 도구에 필요한 파일 시스템 접근 권한을 갖는다. 클라이언트를 분해한 연구자들에 따르면, 백그라운드의 "코드베이스 인덱싱" 루틴이 로그인 시, 프로젝트를 열 때, 또는 에이전트의 고급 기능을 켤 때 작동했다——그 어느 것도 "내 코드를 업로드하라"는 명시적 결정이 아니다. 이 루틴은 작업 공간을, 특히 .git 디렉터리 전체——커밋 히스토리, Git 객체, Git LFS 캐시——를 통째로 수집했다. 그리고 그 결과물을 AES-256-CTR로 압축·암호화하고, Z.ai 서버에서 RSA 공개 키와 알리바바 클라우드(Alibaba Cloud) 오브젝트 스토리지 자격 증명을 받아 아카이브를 올려보냈다.
연구자들이 분석한 한 설치 환경의 수치가 그 규모를 보여준다.
| 수집된 항목 | 세부 내용 |
|---|---|
| 암호화 아카이브 크기 | 313 MB |
| 묶인 파일 수 | 42,411개(345.5 MB 작업 공간에서) |
| 페이로드 중 Git 데이터 비중 | 86.6% |
| 한 스냅샷의 업로드 시도 횟수 | 564회 |
| 암호화 | AES-256-CTR, 복호화 키는 Z.ai가 보유 |
| 트리거 | 로그인 / 프로젝트 열기 / 에이전트 기능 활성화 |
| 동의 확인 | 없음 |
크기보다 더 중요한 두 가지가 있다. 첫째, 동의 단계가 없었다——로그인만으로 충분했다. 둘째, 복호화 키를 Z.ai가 쥐고 있었다. 즉 개발자는 벤더의 버킷에 놓인 자기 저장소의 복사본을 읽을 수도, 통제할 수도 없었다. 비공개 코드베이스에서 완전한 Git 히스토리는 흔히 현재의 작업 트리보다 잃었을 때 더 뼈아프다——삭제한 비밀 정보, 내부 브랜치 이름, 소프트웨어가 어떻게 만들어졌는지에 대한 기록 전체를 담을 수 있기 때문이다.
Z.ai의 대응
회사의 명예를 위해 말하자면, 반응은 빠르고 이례적으로 개방적이었다. Z.ai는 보고서가 나온 바로 그날 문제를 인정하고 사과했다. 9월 20일에는 ZCode 클라이언트 소스를 GitHub에 공개했고, 저장소는 하루 만에 수천 개의 스타를 모았다. 회사는 이 공개를 코드를 커뮤니티의 검증에 맡기는 것이라고 규정했다. 9월 21일에는 시정 조치를 내놓았다. 문제의 기능은 새 클라이언트 버전에서 제거되었고, 두 중국 보안 기관——국가 계열의 CAICT(중국정보통신연구원)와 벤더인 NSFOCUS(绿盟科技)——가 검증을 의뢰받았다. CAICT는 스토리지 버킷이 "제로 데이터 상태"에 이르렀고 해당 기능이 사라졌다고 보고했으며, NSFOCUS는 수정된 클라이언트에서 로컬 스냅샷을 다시 생성해 업로드하는 경로를 찾을 수 없었다고 밝혔다. Z.ai는 데이터 객체와 버킷 자체를 삭제했다고 말한다.
문제를 일으킨 뒤 도구를 오픈소스로 공개한 것은 대다수 벤더 이상의 대응이며, 버킷 삭제도 옳은 조치다. 그러나 이 감사들은 "수정 이후"의 세계를 묘사한다. 아카이브가 존재하던 동안 누가 그것을 읽었는지, 얼마나 오래 보관되었는지, 이미 수집된 히스토리가 어떻게 되었는지는 감사가 말하지 않으며, 말할 수도 없다. 감사 보고서 전문은 회사 성명 시점에 공개되지 않았고, 두 감사 기관 모두 Z.ai가 의뢰한 곳이다. 애초에 코딩 보조 도구가 왜 Git 히스토리 전체를 필요로 했는지, 사과는 거기에 직접 답하지 않았다.
Z.ai에 관한 이야기가 아닌 부분
이를 "중국 앱이 데이터로 불안한 짓을 했다"로 치부하고 싶어진다. 그러나 그 틀은 더 쓸모 있는 교훈을 놓친다. AI 코딩 에이전트는 구조상 당신의 소스 트리에 대한 읽기 접근 권한과 제작사로의 살아 있는 연결을 함께 가진 프로그램이다. 문맥을 위해 코드베이스를 인덱싱하는 것이 가치 제안의 본질이며, 그 인덱스를 어딘가로 보내는 것은 설정 플래그 하나로 "기능"이 된다. ZCode는 기록에 남은 사례지만, 그 메커니즘에 한 연구소나 한 나라에 국한된 것은 없다. 이 에이전트들이 무엇을 집으로 보내는지 공개하는 업계 공통의 규범은 없고, 사고가 난 뒤가 아니라 그 전에 감사하는 독립 기구도 없다.
오늘 AI 코딩 에이전트를 쓰는 사람에게 실질적인 대응은 벤더와 무관하게 동일하다. ZCode를 쓴다면 업데이트하라——수정된 클라이언트는 해당 기능을 제거했다. 더 넓게는, 이 에이전트들을 데이터 유출 경로(data-egress surface)로 취급하라. 기본값으로 켜진 인덱싱과 텔레메트리를 확인하고, 내 기기를 떠나도 괜찮은 코드에만 향하게 하며, 민감한 저장소에서는 네트워크 동작을 감시하라. 편리함은 진짜다. 그러나 당신의 코드를 읽는 것이 그것을 보낼 수도 있다는 사실 또한 진짜다.
출처: Tom's Hardware, ZCode source on GitHub (zai-org/ZCode), StableLearn: ZCode Git-history upload incident, RuntimeWire: Z.ai open-sources ZCode after Git-history upload, DEV: ZCode answered its critics — open source, third-party audits, a deleted bucket