ZCode가 전체 Git 기록을 Aliyun OSS로 몰래 업로드합니다

ZCode가 전체 Git 기록을 클라우드로 몰래 업로드합니다

핵심 요약: ZCode(지푸의 공식 AI 코딩 데스크탑)는 사용자가 로그인되어 있을 때마다 전체 .git 기록, LFS 캐시, reflog, 전역 앱 설정을 포함한 전체 작업 공간을 자동으로 패키징하고, 서버에서 제공한 RSA 공개 키로 암호화하여 암호문을 Aliyun OSS로 직접 업로드합니다. 이 업로드 파이프라인은 무조건적으로 실행되며 UI 토글을 통해 끌 수 없고, 복호화 키는 지푸의 백엔드에만 존재하므로 사용자가 로컬에서 데이터를 복호화할 수 없습니다.


시작점: pending 상태에 멈춘 313 MB 암호화 아카이브

  • ~/.zcode 디렉토리(ZCode의 데이터 루트)가 700 MB 이상을 차지하고 있었습니다.
  • ~/.zcode/v2/checkpoints/ 내부에서 313 MB 크기의 baseline.enc 파일이 발견되었으며, 메타데이터에 따르면 이 파일은 345 MB의 작업 공간 스냅샷을 포함하고 있고 564번의 업로드 시도가 실패했음을 나타냈습니다.
  • 이 스냅샷은 전체 저장소 크기가 10 GB인 상업용 프로젝트를 나타냈으며, node_modules를 제외한 패키징된 페이로드는 345 MB, 즉 거의 전체가 지적 재산이었습니다.

업로드 흐름: 클라이언트 측 패키징 → 직접 OSS POST

리버스 엔지니어링된 app.asar는 2단계 파이프라인을 보여줍니다:

  1. 자격 증명 요청 – 클라이언트가 https://zcode.z.ai/api/v1/snapshot/upload-credential로 POST 요청을 보냅니다. 서버는 다음을 반환합니다:
    • 스냅샷 ID,
    • RSA 공개 키(봉투 암호화에 사용),
    • 최대 크기 제한,
    • Aliyun OSS 폼 자격 증명(policy, x-oss-signature), 그리고
    • 동적 객체 키.
  2. 직접 업로드 – 클라이언트는 tar.gz 아카이브를 생성하고 AES-256-CTR로 암호화한 다음, 제공된 공개 키를 사용하여 RSA-OAEP-SHA256으로 대칭 키를 래핑하고 결과물인 *.enc 파일을 Aliyun OSS로 직접 POST합니다. 이후 OSS는 지푸의 백엔드에 콜백하여 수신을 확인합니다.

네트워크 추적 결과 zcode.z.ai와 두 개의 Aliyun OSS 노드에 대한 지속적인 HTTPS 연결이 확인되었습니다.

암호화 키는 서버 전용입니다

구현은 교과서적인 봉투 암호화 방식을 따릅니다:

keyId: "<version>",
keyWrapAlgorithm: "rsa-oaep-sha256",
publicKeySpkiPem: "<server‑provided PEM>"
  • 콘텐츠는 일회용 AES-256-CTR 키로 로컬에서 암호화됩니다.
  • AES 키는 자격 증명 요청 중에 서버가 제공한 RSA 공개 키로 래핑됩니다.
  • 대응하는 개인 키는 클라이언트 머신에 절대 나타나지 않으며, 로컬에서 키를 언래핑하려는 시도는 실패합니다.

결과:

  • 디스크에 저장된 313 MB의 암호문은 사용자나 ZCode 클라이언트가 복호화할 수 없습니다.
  • 지푸의 백엔드만이 스냅샷을 복호화할 수 있으며, 이는 사실상 서비스가 전체 저장소 기록에 대한 무제한 읽기 권한을 갖게 됨을 의미합니다.

실제로 업로드되는 데이터: 86 %가 .git

패키징 중에 생성된 매니페스트(일반 텍스트로 저장됨)에는 42,411개의 파일이 나열되어 있습니다. 크기 분석:

경로 크기 페이로드 비율 주요 내용
.git/lfs/ 196.1 MB 56.8 % 다운로드된 모든 대용량 바이너리 자산
.git/objects/ 102.2 MB 29.6 % 전체 커밋 객체 저장소(커밋, 트리, 블롭)
.git/logs/ 0.6 MB 0.2 % Reflog, 로컬 브랜치 기록
소스 코드 및 문서 ~46.2 MB 13.4 % src/, 설정 파일, 문서

따라서 업로드된 페이로드의 **86.6 %**는 원시 Git 데이터이며, 다음을 노출합니다:

  • 나중에 삭제된 과거의 API 키 및 비밀 정보.
  • 출시되지 않은 기능을 드러내는 푸시되지 않은 브랜치 이름.
  • 내부 호스트 이름과 저장소 URL이 포함된 .git/config 항목.

추가 매니페스트(repo_snapshot_extra_manifest)는 전역 ZCode 설정 파일을 해시하고 모든 스냅샷과 함께 번들로 묶습니다.

UI 토글은 캡처를 막지 못합니다

UI에는 두 가지 설정이 나타납니다:

설정 의도된 효과 실제 효과
Optimize Experience (optimizeAgentExperienceEnabled) 텔레메트리 / 모델 학습 데이터 전송 억제 모델 학습을 위한 데이터 전송만 비활성화; 스냅샷 캡처는 계속 실행됨
Repo Snapshot Indexing (repoSnapshotIndexingEnabled) 스냅샷 기능 비활성화 이미 업로드된 스냅샷의 서버 측 인덱싱만 중지; 로컬 패키징 및 업로드는 계속됨

코드 검사 결과 스냅샷 사이드카는 시작 시 무조건 인스턴스화됩니다. 유일한 제어 조건은 tokenProvider에서 제공하는 유효한 JWT 토큰뿐입니다. 캡처 트리거는 모든 LLM 프롬프트 이전(captureBeforePrompt)과 repo-wiki-update로 태그된 작업 완료 시점에 발생합니다. 단일 세션에서 수십 개의 캡처 이벤트가 생성될 수 있습니다.

개인정보 처리방침의 누락

ZCode의 개인정보 처리방침은 "대화 중에 제출된 텍스트, 파일 및 코드"를 수집한다고 명시하고 있으며, 이는 LLM 컨텍스트에 대한 표준적인 내용입니다. 그러나 방침, FAQ 및 변경 로그에는 자동 전체 작업 공간 패키징이나 Git 기록 유출에 대한 언급이 전혀 없습니다. 유일한 관련 조항은 "최적화 프로그램은 기본적으로 꺼져 있으며, 동의 없이 입력 내용이 학습에 사용되지 않는다"는 일반적인 문구뿐입니다.

방어 조치: 체크포인트 디렉토리 잠그기

보류 중인 아카이브를 삭제해도 새로운 캡처가 트리거될 뿐입니다(재시도 카운터가 증가함). 확실한 완화 방법은 ~/.zcode/v2/checkpoints 디렉토리를 변경 불가능(immutable)하게 만들어 클라이언트가 새 아카이브를 쓰지 못하게 하는 것입니다.

macOS

rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
chflags uchg ~/.zcode/v2/checkpoints   # 변경 불가능 플래그 설정
# 확인: touch 명령어가 "Operation not permitted"로 실패해야 함

Linux

rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
sudo chattr +i ~/.zcode/v2/checkpoints   # 변경 불가능 속성 설정
# 확인: touch 명령어가 "Operation not permitted"로 실패해야 함

영향: 캡처 파이프라인은 아카이브를 쓸 수 없을 때 중단되므로 데이터가 업로드되지 않습니다. 그 대가로 ZCode의 "체크포인트 롤백 / 타임라인" UI 기능을 사용할 수 없게 되지만, 일반적인 채팅, 자동 완성 및 도구 실행은 정상적으로 작동합니다. 복구하려면 변경 불가능 플래그를 제거하십시오(macOS에서는 chflags nouchg, Linux에서는 chattr -i).


커뮤니티 반응 및 공식 대응

  • Hacker News 댓글에서는 다른 AI 에이전트가 도트파일을 읽는 문제, 샌드박싱의 무용성, 중국 AI 공급업체에 대한 불신 등이 제기되었습니다.
  • 지푸의 성명(댓글에 스크린샷 링크됨)은 해당 동작이 로컬 저장소 인덱싱 및 임시 Wiki 생성을 위한 초기 출시 "코드베이스 인덱싱" 기능에서 비롯된 것이라고 주장했습니다. 성명은 업로드된 데이터가 Wiki 생성 직후 즉시 파기되며 문제가 수정되었음을 주장했고, 사과와 함께 사용자들에게 1주일간의 할당량 초기화를 제공했습니다.
  • 비평가들은 성명(데이터가 임시적이고 파기됨)과 기술적 증거(서버가 보유한 키로 OSS에 지속적으로 암호화 업로드됨) 사이의 불일치를 지적합니다.

결론

ZCode의 백그라운드 프로세스는 로그인한 사용자의 전체 작업 공간(전체 Git 기록 포함)을 캡처하여 사용자가 제어할 수 없는 방식으로 제3자 클라우드에 암호화하여 업로드합니다. 암호화 키는 지푸의 서버에만 존재하므로 서비스 측에서 원할 때 언제든지 데이터를 복호화할 수 있습니다. 이러한 수준의 데이터 수집을 받아들일 수 없는 사용자는 ZCode 체크포인트 디렉토리를 잠그거나(또는 앱을 삭제하여) 추가적인 유출을 방지해야 합니다.

Sources

관련