ZCode Git Snapshot-incident: wat AI-codeeragenten kunnen zien, uploaden en onthouden

Eva Wong is de Technisch Schrijver en en vaste knutselaar bij ZimaSpace. Een levenslange geek met een passie voor homelabs en open-source software, zij is gespecialiseerd in het vertalen van complexe technische concepten naar toegankelijke, praktische handleidingen. Eva gelooft dat zelf-hosting leuk moet zijn, niet intimiderend. Met haar tutorials stelt ze de community in staat om hardware-setup te ontrafelen, van het bouwen van hun eerste NAS tot het beheersen van Docker-containers.

Het incident met repositoryuploads van ZCode gaat verder dan één codeertool. Het legt een beveiligingsvraag bloot die ontwikkelaars steeds vaker moeten beantwoorden voordat ze een AI-agent toegang geven tot een project: betekent “toegang tot de repository” het huidige bestand, de werkboom of jaren aan Git-geschiedenis?

Dat onderscheid is belangrijk, omdat .git informatie kan bevatten die niet langer zichtbaar is in de huidige codebase, waaronder verwijderde geheimen, oude bronversies, reflogs, LFS-middelen en de lokale branchgeschiedenis. ZCode zegt dat het betreffende uploadgedrag is verholpen, maar het incident laat een blijvende les achter: AI-codeeragenten hebben expliciete gegevensgrenzen nodig, niet alleen toestemming om “toegang tot de repo” te krijgen.

Wat gebeurde er werkelijk met ZCode?

Op 18 september 2026 publiceerde ontwikkelaar ferstar een reverse-engineeringonderzoek naar ZCode 3.12.3, nadat hij onverwacht grote bestanden in de lokale gegevensmap van de applicatie had opgemerkt.

Volgens het oorspronkelijke onderzoek maakte de client versleutelde worksamples die zowel bronbestanden als .git, Git LFS-objecten, reflogs en repositorymetagegevens konden bevatten. De client bevatte ook een pipeline voor het verkrijgen van uploadreferenties en het verzenden van versleutelde archieven naar Alibaba Cloud OSS.

ZCode erkende vervolgens uploads van repositorygegevens die verband hielden met het indexeren van codebases en Repo Wiki, bood excuses aan, zei dat het gedrag was verholpen en kondigde plannen aan voor opensource- en externe beoordeling. In de berichtgeving uit die periode werden de belangrijkste punten van ZCodes reactie opnieuw weergegeven.

Bewering Bewijs
Oudere ZCode-versies maakten brede repositorysnapshots Ondersteund door reverse-engineering en lokaal snapshotbewijs
Er bestond een uploadpipeline Ondersteund door reverse-engineering van het clientgedrag
Een kleine repository heeft de service succesvol bereikt Bevestigd door de vervolgtest van de onderzoeker
De commerciële repository van 313 MB is succesvol geüpload Nee - die upload is mislukt
De huidige ZCode gebruikt nog steeds dezelfde pipeline Geen bewijs; de onderzoeker meldt dat het oude pad is verwijderd

Dit is het eerste belangrijke informatiegat dat moet worden gedicht: het incident was echt, maar sommige virale samenvattingen overdreven wat er daadwerkelijk succesvol was overgedragen.

Is de privérepository van 313 MB daadwerkelijk geüpload?

Nee.

De snapshot van het commerciële project bevatte ongeveer 42.000 bestanden en resulteerde in een versleuteld archief van ongeveer 313 MB. Volgens de update van de onderzoeker van 19 september bleef deze lokaal in behandeling status after 564 failed attempts because it exceeded the uploadlimiet. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Een afzonderlijke, kleinere openbare repository bereikte de dienst wel. Deze bevatte 538 bestanden en leverde een veel kleinere versleutelde payload op.

Repository Waargenomen resultaat
313MB commerciële repository Lokaal verpakt, herhaaldelijk geprobeerd, upload mislukt
Kleine openbare repository Succesvol geaccepteerd door de externe dienst

De juiste conclusie is daarom niet “elke ZCode-repository is geüpload”. De conclusie is dat de oude client een functioneel mechanisme voor het uploaden van repositories bevatte, waarvan het daadwerkelijke succes afhankelijk was van de snapshot.

Waarom de map `.git` het belangrijkste onderdeel van dit incident is

In de grote snapshot van de onderzoeker bestond het grootste deel van de payload niet uit de huidige broncode.

Snapshotinhoud Geschat aandeel
.git/lfs/ 56.8%
.git/objects/ 29.6%
.git/logs/ 0.2%
Huidige broncode en documentatie 13.4%

Dat betekent dat ongeveer 86.6% van de snapshot uit .git kwam. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Dit verandert de beveiligingsinterpretatie volledig.

Een AI-agent die de huidige bronboom leest, ziet mogelijk wat de ontwikkelaar tegenwoordig bewust bewaart. Toegang tot de Git-geschiedenis kan onthullen wat de ontwikkelaar dacht al te hebben verwijderd.

Mogelijke historische blootstelling omvat:

  • verwijderde bronbestanden
  • oude API-sleutels of tokens
  • eerdere interne eindpunten
  • verlaten functies
  • historische configuratie
  • lokale branchactiviteit
  • toestanden die alleen in de reflog voorkomen
  • grote historische LFS-assets

De Git-reflogdocumentatie legt uit dat reflogs eerdere waarden van lokale verwijzingen vastleggen. Die records kunnen lokaal bestaan, zelfs wanneer de bijbehorende geschiedenis nooit naar een externe repository is gepusht.

Dit geeft ons een nuttige beveiligingsregel:

“Mijn project lezen” en “mijn Git-geschiedenis lezen” zouden afzonderlijke machtigingen moeten zijn.

Waarom verwijderde geheimen nog steeds kunnen bestaan nadat je ze uit de code hebt verwijderd

Het verwijderen van inloggegevens uit het nieuwste bestand verwijdert ze niet noodzakelijkerwijs uit Git.

Een ontwikkelaar kan per ongeluk een API-sleutel vastleggen, deze in de volgende commit verwijderen en een volledig schoon huidig bestand zien. Het eerdere blob-object kan via de repositorygeschiedenis nog steeds bereikbaar zijn.

De richtlijnen van GitHub voor het verwijderen van gevoelige gegevens bevelen expliciet aan om blootgelegde inloggegevens in te trekken of te rouleren voordat de geschiedenis wordt herschreven.

Die volgorde is belangrijk:

  1. Maak de inloggegevens ongeldig.
  2. Verwijder gevoelige geschiedenis waar dat gepast is.
  3. Voorkom dat het geheim opnieuw wordt vastgelegd.

Voor AI-codeagents betekent dit dat een functie die rekening houdt met de geschiedenis toegang kan krijgen tot gegevens die een normale editorweergave niet langer toont.

Dit verklaart ook waarom een alleen-lezen-agent niet automatisch een laag risico inhoudt. Alleen-lezen-toegang kan nog steeds waardevolle informatie lekken als het bereik van het bestandssysteem te groot is of als opgehaalde inhoud naar een extern model wordt verzonden.

Modelcontext, telemetrie, training en uploads van repositories zijn niet hetzelfde

Een andere belangrijke les is dat één enkele schakelaar voor “privacy” niet elk type gegevensstroom kan vertegenwoordigen dat een AI-codeertool kan hebben.

Gegevensstroom Typisch doel
Inferentiecontext Code verzenden die nodig is om de huidige taak te beantwoorden
Telemetrie Crashes, betrouwbaarheid en gebruik meten
Gegevens voor modeltraining Toekomstige modellen of productgedrag verbeteren
Repository-index Een project efficiënter doorzoeken en begrijpen
Cloudsnapshot Een bredere werkruimtestaat behouden
Synchronisatie / back-up Gegevens tussen sessies of apparaten herstellen

De betreffende ZCode-versie is belangrijk omdat de onderzoeker meldde dat het uitschakelen van de optie voor optimalisatie/training de afzonderlijke snapshot-pijplijn niet uitschakelde. In het rapport werd ook beweerd dat de schakelaar voor Repo Snapshot Indexing in die versie niet verhinderde dat er pogingen werden gedaan om pakketten te maken en te uploaden. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Dit leidt tot een regel die veel verder gaat dan ZCode:

“Train niet op mijn gegevens” betekent niet “verzend mijn gegevens niet”.

Een cloudmodel heeft nog steeds context voor inferentie nodig. Telemetrie kan via een ander eindpunt worden verstuurd. Synchronisatie kan een andere kopie bewaren. Het indexeren van de repository kan een eigen gegevensstroom hebben.

Hetzelfde onderscheid doet zich voor wanneer een lokale AI-agent cloudtools gebruikt: privacy hangt af van de exacte gegevens die de grens overgaan, niet simpelweg van waar het hoofdproces van de agent draait.

Versleuteling beantwoordt de belangrijkste privacyvraag niet

De betreffende ZCode-snapshot werd vóór het uploaden versleuteld.

Het reverse-engineeringrapport beschrijft AES-256-CTR-versleuteling voor het archief en RSA-OAEP-SHA256-wrapping voor de symmetrische sleutel. De openbare RSA-sleutel werd door de dienst verstrekt, terwijl de bijbehorende privésleutel niet lokaal was opgeslagen. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

Dat beschermt gegevens op een andere manier dan end-to-end-versleuteling die door de gebruiker wordt beheerd.

Bescherming Wat het betekent
TLS / transportversleuteling Beschermt gegevens tijdens het transport over het netwerk
Cloudversleuteling bij opslag Beschermt opgeslagen bytes tegen bepaalde infrastructuurbedreigingen
Door de provider beheerde sleutel De dienst kan technisch gezien de mogelijkheid behouden om te ontsleutelen
Door de gebruiker beheerde end-to-end-sleutel De dienst beschikt niet over de vereiste ontsleutelingssleutel

Dus “de repository was versleuteld” is onvolledig.

De belangrijkere vraag is:

wie kan het ontsleutelen?

Datzelfde principe geldt voor private RAG, cloudback-ups, AI-geheugen en elk systeem dat beweert dat gegevens beschermd zijn omdat ze versleuteld zijn.

Hoeveel toegang tot een repository heeft een codeeragent daadwerkelijk nodig?

Codeeragents hebben legitiem meer context nodig dan traditionele autocomplete. Voor een refactor van de hele repository kunnen veel bestanden nodig zijn. Een debuggingagent kan tests, afhankelijkheidsmetadata, Git-status en builduitvoer nodig hebben.

Maar “de agent heeft mogelijk brede context nodig” betekent niet “elke functie moet elk byte in de repository ontvangen”.

Gegevensscope Verstandige standaardinstelling
Huidig bestand Toestaan voor relevante taken
Gerefereerde bronbestanden Toestaan
Volledige bronboom Taakafhankelijk
.gitignore-uitgesloten bestanden Uitsluiten
.env / referenties Blokkeren
.git objecten Uitsluiten tenzij expliciet vereist
Reflogs Standaard uitsluiten
Git LFS-cache Uitsluiten tenzij vereist
SSH-/cloudreferenties Blokkeren
Volledige snapshot op afstand Expliciete toestemming

Dit is een versie van hetzelfde principe voor gegevenstoegang als in een vertrouwensgrens voor tooluitvoering: het vermogen van het model om iets aan te vragen mag niet automatisch de bevoegdheid verlenen om alles in de omgeving te openen of te exporteren.

Voor codeeragents hebben we twee onafhankelijke grenzen nodig:

  • Actiegrens: wat kan de agent wijzigen of uitvoeren?
  • Gegevensgrens: wat kan de agent lezen of verzenden?

Een agent zonder schrijfrechten kan nog steeds ernstige privacyrisico's veroorzaken als de lees- en netwerkrechten onbeperkt zijn.

Wat heeft ZCode na het incident veranderd?

Het incident moet niet worden beschreven alsof bekend is dat hetzelfde gedrag in huidige ZCode-versies voorkomt.

Bij een vervolginspectie van ZCode 3.14.0 meldde de onderzoeker dat de eerdere upload-sidecar was verwijderd en dat het oude credential-endpoint 404 retourneerde. Het geïnspecteerde pad behield lokale checkpointfunctionaliteit zonder het eerdere mechanisme voor uploaden op afstand. ([blog.ferstar.org](https://blog.ferstar.org/en/posts/zcode-silent-workspace-snapshot-upload/))

De huidige Repo Wiki-documentatie beschrijft ook een veel beperktere gegevensgrens.

Er staat dat de Wiki-context het volgende uitsluit:

  • .git
  • afhankelijkheidsmappen
  • builduitvoer
  • caches
  • lokale runtime-status
  • ondersteund .gitignore uitsluitingen
  • vermoedelijk gevoelige configuratiebestanden
  • symlinkdoelen

De uitvoer van Repo Wiki wordt gedocumenteerd als lokale toepassingsgegevens en niet als inhoud die terug naar de repository wordt geschreven.

Dit verschilt wezenlijk van het snapshotgedrag dat in versie 3.12.3 werd gemeld.

Is open source voldoende om een codeeragent privé te maken?

Nee.

Open source kan het voor een klant eenvoudiger maken om een toepassing te controleren, maar een open-sourcetoepassing kan nog steeds broncode naar cloudmodellen sturen, telemetrie uploaden, status synchroniseren of afhankelijk zijn van opslag die door een provider wordt beheerd.

De nuttigere checklist is:

Vraag Beveiligingseigenschap
Wat kan de agent lezen? Lokale gegevensscope
Wat kan de machine verlaten? Grens voor uitgaand verkeer
Waarom wordt dit verzonden? Doelbeperking
Hoelang worden ze bewaard? Persistentie
Wie beheert de encryptiesleutels? Ontsleutelingsbevoegdheid
Kan het gedrag worden uitgeschakeld? Gebruikerscontrole
Kunnen buitenstaanders dit verifiëren? Controleerbaarheid

Daarom wordt een private AI-architectuur meer bepaald door de gegevensstroom dan door de vraag of de softwarelicentie toevallig open source is.

Hoe moeten ontwikkelaars een nieuwe AI-codeeragent controleren?

Ontwikkelaars hoeven niet elke app volledig te reverse-engineeren, maar een nieuwe agent mag niet als eerste testomgeving toegang krijgen tot een gevoelige commerciële repository.

  1. Lees de documentatie over gegevensverwerking. Maak onderscheid tussen inferentie, telemetrie, training, indexering, synchronisatie en back-ups.
  2. Controleer uitsluitingsregels. Zoek specifiek naar .git, .env, genegeerde bestanden, afhankelijkheden, inloggegevens en symbolische koppelingen.
  3. Begin met een wegwerpbare repository. Gebruik eerst niet-gevoelige code.
  4. Inspecteer lokale app-opslag. Onverwacht grote caches of snapshots kunnen de verborgen reikwijdte van gegevens onthullen.
  5. Houd uitgaand verkeer in de gaten. Firewall-, DNS-, proxy- of routerlogboeken kunnen externe diensten identificeren.
  6. Gebruik onschadelijke canarybestanden. Test of niet-gerelateerde bestanden in de modelcontext of uploadcontext terechtkomen.
  7. Verleen eerst de minimaal benodigde bevoegdheden. Breid deze alleen uit wanneer een specifieke taak dat vereist.

Hier helpt ook agentontwerp volgens het principe van minimale bevoegdheden, zolang ‘alleen-lezen’ wordt gecombineerd met beperkte paden en gecontroleerde uitgaande gegevens, in plaats van onbeperkte zichtbaarheid van de repository.

Wat een lokaal-eerst codeeragent anders zou moeten doen

Lokaal-eerst betekent niet dat elke taak offline moet worden uitgevoerd.

Dit betekent dat lokale gegevens standaard binnen de lokale vertrouwensgrens blijven en externe verzending doelbewust plaatsvindt in plaats van incidenteel.

Lokaal-eerstprincipe Voorkeursgedrag
Repository-indexering Houd symbolen, embeddings en metadata waar praktisch lokaal
Context van het externe model Verstuur alleen code die relevant is voor de taak
Git-geschiedenis Sluit ze uit, tenzij de taak expliciet om geschiedenis vraagt
Geheimen Filter voordat je de context samenstelt
Externe upload Toon de reikwijdte en vraag expliciete toestemming
Toestemming voor training Scheid dit van de inferentiebevoegdheid
Gevoelige repositories Bied volledig lokale paden voor modellen en indexering
Netwerkafhankelijkheid Documenteer wat offline niet meer werkt

Dit principe is breder dan coderen. Een echt lokale AI-workflow moet het kritieke datapad van begin tot eind lokaal houden; een lokaal geïnstalleerd model is niet voldoende als embeddings, indexering, authenticatie of bestandsverwerking stilletjes afhankelijk zijn van een externe dienst.

Voor hybride systemen is het sterkere patroon om privébestanden achter een lokale service te houden en alleen de minimaal vereiste context beschikbaar te stellen aan goedgekeurde externe tools. Dat is dezelfde aanpak die wordt gebruikt bij het ontwerpen van een agent die clouddiensten gebruikt zonder het volledige lokale bestandssysteem bloot te stellen.

De grotere les: toegang tot repositories is een beveiligingsmachtiging

De blijvende les van ZCode is niet: “gebruik nooit cloudcodeeragents”. Het is dat toegang tot repositories op zichzelf een beveiligingsmachtiging is geworden.

Een moderne codeeragent kan het volgende combineren:

  • het lezen van volledige projecten
  • Git-bewustzijn
  • terminaluitvoering
  • browsertoegang
  • externe modellen
  • achtergrondtaken
  • langetermijngeheugen
  • autonome bestandsbewerking

Dat betekent dat ontwikkelaars meer moeten beoordelen dan alleen welke opdrachten een agent kan uitvoeren.

Ze moeten zich ook afvragen:

  • Welke bestanden kan het bekijken?
  • Hoe ver terug in de geschiedenis kan het kijken?
  • Welke van die gegevens verlaten de machine?
  • Welke service ontvangt ze?
  • Hoelang worden ze bewaard?
  • Wie kan deze ontsleutelen?

Voor AI-codeeragents gaat privacy niet langer alleen over de vraag of het model op je code wordt getraind. Het gaat erom of de gegevensgrens van de agent overeenkomt met de taak die je daadwerkelijk hebt gevraagd uit te voeren.

Veelgestelde vragen over het incident met het uploaden van repositories door ZCode

Heeft ZCode de volledige privérepository van 313 MB van de onderzoeker geüpload?

Nee. De onderzoeker meldde dat de snapshot van het grote commerciële project was verpakt en herhaaldelijk in de uploadwachtrij was geplaatst, maar vanwege de omvang niet kon worden geüpload. Een afzonderlijke, kleinere openbare repository werd wel door de service geaccepteerd.

Kan `.git` geheimen bevatten die niet meer in de huidige code staan?

Ja. Git-objecten en historische commits kunnen eerdere versies van bestanden bewaren nadat gevoelige inhoud uit de werkmap is verwijderd. Reflogs kunnen ook lokale referentiegeschiedenis bevatten die mogelijk nooit op afstand is gepusht.

Stopt het uitschakelen van AI-training een codeeragent ervan om code te uploaden?

Niet noodzakelijk. Training, inferentie, het indexeren van repositories, telemetrie, cloudsynchronisatie en back-ups zijn afzonderlijke gegevensstromen. Het uitschakelen van toestemming voor modeltraining schakelt niet automatisch de gegevensoverdracht uit die voor een andere cloudfunctie vereist is.

Heeft ZCode het probleem met de repository-snapshot opgelost?

ZCode zegt dat het probleem is opgelost. De oorspronkelijke onderzoeker meldde dat het oude pad voor uploaden op afstand ontbrak in versie 3.14.0, terwijl de huidige Repo Wiki-documentatie expliciet uitsluit .git, afhankelijkheden, builduitvoer, caches en verschillende gevoelige bestandscategorieën uit de Wiki-modelcontext.

Is een AI-codeeragent met open source automatisch privé?

Nee. Open source verbetert de controleerbaarheid, maar privacy hangt nog steeds af van welke bestanden de tool leest, welke gegevens het apparaat verlaten, welke clouddiensten ze ontvangen, hoelang ze worden bewaard en wie de encryptiesleutels beheert.

Tech & AI HUB

Meer om te lezen

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.