Drücke „Enter”, um zum Inhalt zu springen.

AGENTS.md beveiliging: hoe vreemde bestanden AI-agents sturen

0
Dr. DSGVO Newsletter detected: Extended functionality available
More articles · Website-Checks · Live Offline-AI

Een onopvallend tekstbestand in de map Downloads was in één geval genoeg om een AI-codeeragent een kwaadaardig pakket te laten installeren. Dit artikel over AGENTS.md beveiliging beschrijft wat er is gebeurd, welke instructiebestanden Codex, Claude Code en Cursor laden en welke instellingen en maatregelen de schade kunnen voorkomen.

Een vondst op de computer van een klant en de gevolgen

Het beveiligingsbedrijf Forever Security ontdekte het volgende: op de computer van een klant stond in de map Downloads een instructiebestand met de naam AGENTS.md, dat een AI-codeeragent ertoe moest brengen een npm-pakket te installeren. Het bestand is geen programma, maar werkt wel als een handleiding voor wat de agent moet doen.

Wie niet weet wat CLAUDE.md is, gebruikt AI "alleen" als chatbot. Dat is niet verkeerd (en vaak zelfs aan te raden), maar het verhindert inzicht in wat de AI-systemen van vandaag maximaal kunnen.

Wat er is gebeurd: vondst in de map Downloads, natest en succespercentages

Het uitgangspunt was een echte vondst. Het bestand stond in de map Downloads van een ontwikkelaar. Die map was tegelijk de werkmap van de agent. De agent wilde het npm-pakket function-color installeren. Volgens eigen zeggen hield Forever Security hem tegen voordat er code werd uitgevoerd. Hoe het bestand in de map terechtkwam, konden de onderzoekers niet achterhalen.

Het pakket function-color haalt een ander pakket binnen met de naam function-flag. Dat downloadt Windows-malware en start die. CloudSEK en Checkmarx noemen de campagne MALFEX.

Natest met Codex

Forever Security bootste de aanval na in een geïsoleerde virtuele machine. Het echte bestand droeg Codex op een server te registreren in het bestand ~/.codex/config.toml en een opdracht uit te voeren die het pakket installeert. Omdat deze configuratie geldt voor alle Codex-sessies op de computer, werkt de wijziging blijvend en in elke map. Het succespercentage lag rond de 90 procent.

Natest met Claude Code

Bij Claude Code ging het om een ander bestand. Een geprepareerde CLAUDE.md deed zich voor als de inrichting van een interne gateway en moest de agent ertoe brengen een vreemd adres als API-doel in een projectinstellingenbestand te schrijven. Dan zou het API-verkeer naar een server van de onderzoekers lopen. Daarmee komt het aanmeldtoken van de sessie vrij, en de server kan opdrachten terugsturen die de agent uitvoert. Claude Code vraagt voor zulke schrijfacties gewoonlijk om bevestiging en weigert verdachte vaak. Pas een lange motivering die bijna als ontwikkelaarsdocumentatie klonk, leverde in ongeveer de helft van de gevallen een goedkeuring op.

De twee cijfers zijn niet direct vergelijkbaar. Het gaat om verschillende agents, verschillende bestanden en verschillende doelen. Steekproefgrootte en testconfiguratie (sandbox, goedkeuringsmodus) zijn onduidelijk.

Telemetrie: hoe vaak wordt een agent in de map Downloads gestart?

Ongeveer de helft van de klanten van Forever Security start een codeeragent in de map Downloads, en ongeveer een kwart van de sessies opent een browser. BleepingComputer noemt meer dan 1.300 Claude Code-sessies vanuit deze map. Beide zijn opgaven van de leverancier over de eigen klantenkring, een onafhankelijke controle is er niet. Of aanvallers zulke bestanden in de praktijk echt via browserdownloads plaatsen, is niet aangetoond. De proof of concept downloadde alleen een onschuldig bestand.

Aanvalsketen: bestand in de map Downloads, agent start, bestand wordt geladen, kwaadaardig pakket
De aanvalsketen in vier stappen; hoe de download bij de klant terechtkwam, is niet aangetoond.

AGENTS.md beveiliging: waarom vreemde instructiebestanden een risico zijn

Codeeragents lezen bij het starten instructiebestanden uit de werkmap. Daarin staan bouwinstructies, stijlregels of testopdrachten. De agent behandelt deze inhoud als aanwijzingen van de gebruiker. Hij maakt niet betrouwbaar onderscheid of het bestand van het team komt of van een vreemde bron. Dat is de kern van een indirecte prompt injection bij een codeeragent: de instructie komt niet uit het invoerveld, maar uit de context.

Twee eigenschappen die op zich onschuldig zijn, vormen samen de keten. Ten eerste vertrouwen agents de bestanden in de geopende map. Ten tweede kunnen websites zonder te vragen bestanden in de map Downloads zetten, als de browser zo is ingesteld. Chrome, Edge en Firefox slaan standaard in deze map op zonder naar de opslaglocatie te vragen en tonen alleen een melding. Brave vroeg in de test eerst om bevestiging. Het bestand krijgt de naam en inhoud die de website opgeeft.

Instructiebestanden zijn context, geen configuratie. Bindend is alleen wat rechten en sandbox technisch afdwingen.

De documentatie van Claude Code beschrijft CLAUDE.md als context en niet als afgedwongen configuratie. Voor blokkades raadt ze hooks aan. Daaruit volgt de basisregel voor al het andere: wat alleen in de tekst van een bestand staat, kan een agent opvolgen of negeren. Wat in de rechten staat, dwingt het programma af.

De browser is niet de enige weg

De map Downloads staat in dit geval centraal, maar niet als enige. De NVIDIA Developer Blog beschrijft een verwante route: een gecompromitteerd afhankelijkheidspakket maakt zelf een AGENTS.md aan. Ook gekloonde repositories, uitgepakte archieven en buildscripts kunnen vreemde instructiebestanden in een projectmap brengen. De startlocatie verkleint dus het aanvalsoppervlak, maar neemt het niet weg.

Duiding: wat onderzoekers en leveranciers zeggen

De onderzoekers van Forever Security stellen dat er voor OpenAI en Anthropic niets te patchen valt. De agent volgt zijn instructiebestand zoals bedoeld, vergelijkbaar met een browser die een phishingpagina weergeeft. Dat is de inschatting van de onderzoekers. Een eigen verklaring van de leveranciers over deze aanval bevatten de twee berichten niet. BleepingComputer wijst er alleen op dat beide leveranciers aanraden agents in de betreffende projectmap te starten. De verantwoordelijkheid ligt daarmee bij de gebruikers en bij de organisaties die agents inzetten.

De risico's van autonome agents zijn een groter onderwerp. Artikelen over macht zonder controle bij AI-agents en over het tijdperk van AI-agents leggen uit waarom agents met eigen handelingsbevoegdheden andere beschermingsmaatregelen nodig hebben dan klassieke software.

Welke instructiebestanden Codex, Claude Code en Cursor laden

Doorslaggevend is wat als projectmap geldt: de map waarin de agent wordt gestart. Wie in de map Downloads start, maakt van elk bestand dat daar staat projectcontext. Het volgende overzicht vat de documentatie van de leveranciers samen (stand 26-10-2026). De documentatie verandert snel, bij twijfel geldt de actuele versie.

Tabel: welke instructiebestanden Codex, Claude Code en Cursor laden, geordend naar globale map en projectmap
Laadpaden van de drie agents volgens de documentatie van de leveranciers, stand 26-10-2026.

Codex

Volgens de documentatie leest Codex eerst een globaal bestand in de Codex-map (~/.codex, aan te passen via CODEX_HOME), namelijk AGENTS.override.md of AGENTS.md. Daarna volgen bestanden van de projectroot, meestal de Git-hoofdmap, tot aan de huidige map. Per map wordt hoogstens één bestand meegenomen: AGENTS.override.md, AGENTS.md of een geconfigureerde vervangende naam. De totale grens ligt bij 32 KiB. Wordt er geen projectroot gevonden, dan telt alleen de huidige map. Precies dat geldt voor de map Downloads, want daar staat meestal geen Git-repository.

Claude Code en CLAUDE.md beveiliging

Volgens de geheugendocumentatie laadt Claude Code CLAUDE.md en CLAUDE.local.md uit de werkmap en uit alle mappen daarboven, en indien nodig ook uit submappen. Daarbij komen ~/.claude/CLAUDE.md, het beheerde beleid van het systeem en bestanden in .claude/rules/. Voor CLAUDE.md beveiliging betekent dat: ook een te hoog startpunt, zoals de thuismap, vergroot het oppervlak, omdat bestanden daarboven en ernaast worden meegelezen.

AGENTS.md leest Claude Code volgens de documentatie sinds versie 2.1.277. Standaard gebeurt dat alleen als er in de werkmap of daarboven geen CLAUDE.md of CLAUDE.local.md staat. Via de instelling voor projectinstructies is dat te wijzigen: claude-md-or-agents-md is de standaard, claude-md-and-agents-md leest beide, managed-only laat alleen centraal beheerde instructies toe.

Cursor

Volgens de documentatie kent Cursor projectregels in .cursor/rules/ (bestanden in het formaat .mdc, ook in submappen) en AGENTS.md in de projectroot en in submappen. Geneste bestanden gelden voor hun eigen bereik, het meest specifieke wint. Daarnaast zijn er persoonlijke User Rules in de instellingen en Team Rules via het dashboard.

Configuratiebestanden als eigenlijk doelwit

Het geval laat zien dat het instructiebestand vaak alleen het gereedschap is. Het doel zijn configuratiebestanden waarin een wijziging blijvend werkt. Bij Codex is dat ~/.codex/config.toml, waarvan een wijziging alle sessies raakt. Bij Claude Code is het het instellingenbestand .claude/settings.json, waarin via een omgevingsvariabele het API-doel kan worden ingesteld. Beide bestanden horen daarom op de lijst van bestanden die een agent niet zonder bevestiging mag wijzigen.

AI-codeeragents beveiligen: rechten, hooks en Codex-sandbox

De voor de hand liggende vraag is of het volstaat om de map Downloads te vermijden.

Is het genoeg om AI-codeeragents gewoon niet in de map Downloads te starten?

Nee. De startlocatie verkleint het aanvalsoppervlak, maar beschermt niet tegen vreemde instructiebestanden in gekloonde repositories, uitgepakte archieven of afhankelijkheden. Betrouwbaar beschermen pas afgedwongen grenzen: rechtenregels met bevestiging, een sandbox met netwerk-allowlist, hooks voor geblokkeerde opdrachten en gecontroleerde configuratiebestanden. De startlocatie is de eerste regel, niet de enige.

De maatregelen grijpen op drie plaatsen aan: wat de agent zonder bevestiging mag doen, wat een hook los van het model blokkeert en wat de sandbox technisch begrenst.

Rechtenregels in Claude Code

Claude Code kent regels op de niveaus allow, ask en deny per tool (documentatie over rechten). Standaard vraagt de agent om bevestiging bij shellopdrachten en bestandswijzigingen. Een deny-regel geldt ook als de agent een instructiebestand wil volgen. Een voorbeeld voor het bestand .claude/settings.json:

{
  "permissions": {
    "deny": [
      "Bash(npm install *)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Edit(.claude/**)",
      "Edit(~/.codex/**)"
    ]
  }
}

De schrijfwijze volgt de voorbeelden uit de documentatie: Bash-regels vergelijken de opdrachttekst met * als jokerteken, padregels voor lezen en bewerken gebruiken de syntaxis van gitignore, ~/ staat voor de thuismap. Bestandswijzigingen worden via Edit(…) geregeld, regels voor Write worden volgens de documentatie niet tegen paden getoetst. Een opdrachtblokkade is bovendien geen garantie, want hetzelfde doel is vaak via een andere aanroep te bereiken. Voor wat onvermijdelijk is, zijn hooks en sandbox bedoeld.

Twee gemaksfuncties vragen om voorzichtigheid. Een goedkeuring met "niet meer vragen" geldt afhankelijk van de tool blijvend voor een repository, en in de automatische modi beslist niet meer de mens over elke actie. Geen van beide hoort thuis in omgevingen met vreemde code.

Hooks: blokkades los van het model

Een PreToolUse-hook draait vóór de toolaanroep en kan die blokkeren, ook als het model die juist vindt. De handleiding voor hooks toont het patroon: het script leest de invoer als JSON van de standaardinvoer en sluit af met een exitcode om te blokkeren. Het wordt geregistreerd in het instellingenbestand:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-installs.sh"
          }
        ]
      }
    ]
  }
}

Het script block-installs.sh leest met jq de opdracht uit het veld tool_input.command, toetst die aan een blokkeerlijst (bijvoorbeeld npm install of de combinatie van curl en een shell) of beter aan een allowlist en meldt bij een treffer een reden op de foutuitvoer met exit 2. Een tweede, weinig bekende hefboom is de hook InstructionsLoaded. Die legt geladen instructiebestanden vast. Volgens de documentatie wordt hij echter niet geactiveerd voor een AGENTS.md die via de instelling wordt geladen, maar alleen als een CLAUDE.md die importeert. Een team moet daarom niet alleen op deze hook vertrouwen.

Centrale regels met Managed Settings

Voor teams zijn beheerde instellingen de krachtigste hefboom. Volgens de documentatie over Managed Settings kunnen permissions.deny, sandbox.enabled en env centraal worden afgedwongen. Daarmee zou een via een instructiebestand ondergeschoven API-doel, zoals in de test met Claude Code, veel moeilijker door te voeren zijn. Ter duiding: dit is een conclusie uit de documentatie, geen aangetoond effect in het geval van Forever Security.

Codex: goedkeuringen, vertrouwensniveau en sandboxmodi

Voor de Codex-sandbox en rechten gelden volgens de documentatie over goedkeuringen en beveiliging twee niveaus. Het goedkeuringsbeleid bepaalt wanneer Codex om bevestiging vraagt (bijvoorbeeld on-request of never). De sandboxmodus bepaalt wat technisch mogelijk is: read-only, workspace-write of danger-full-access. In de modus workspace-write staat het netwerk standaard uit.

Daarbij komt een vertrouwensniveau per project in ~/.codex/config.toml (trust_level). Volgens de documentatie geldt in mappen onder versiebeheer de modus Auto, dus schrijven in de werkruimte met bevestiging. In mappen zonder versiebeheer geldt read-only, totdat de map als vertrouwd wordt gemarkeerd. Een map als Downloads geldt zonder markering als niet vertrouwd. Het risico ontstaat wanneer gebruikers de vertrouwensdialoog bevestigen. De vlag –yolo verwijdert sandbox en goedkeuringen en hoort niet thuis in teamrichtlijnen. In welke configuratie Forever Security heeft getest, is niet gemeld. Of de standaardbeschermingsniveaus in de test werkten, is daarom onbekend.

Cursor

Over goedkeuringen voor terminalopdrachten bij Cursor is geen eenduidige opgave van de leverancier beschikbaar. Daarom hier alleen het advies om goedkeuringen voor terminalopdrachten ingeschakeld te laten en de actuele documentatie van de leverancier te controleren.

Sandbox en isolatie: schade beperken, ook als de agent het bestand volgt

Een sandbox beperkt wat een agent kan doen, zelfs als hij een vreemde instructie volgt. De sandbox van Claude Code staat schrijftoegang toe tot de werkmap en tijdelijke mappen. Netwerktoegang loopt via een proxy met een lijst van toegestane domeinen, die standaard leeg is. Beschermde paden zoals de instellingen van Claude Code, het shell-opstartbestand .bashrc en Git-hooks blijven alleen-lezen. Een voorbeeld:

{
  "sandbox": {
    "enabled": true,
    "network": {
      "allowedDomains": ["github.com", "*.npmjs.org"]
    },
    "allowUnsandboxedCommands": false
  }
}

De documentatie noemt ook grenzen. De sandbox staat standaard uit. De leestoegang is breed, inloggegevens moeten gericht worden afgeschermd. De bescherming geldt alleen voor shellopdrachten en hun child-processen, niet voor de ingebouwde bestandstools, MCP en hooks. Zonder allowUnsandboxedCommands: false kan een mislukte opdracht buiten de sandbox worden herhaald. Onder Windows draait de sandbox niet native, daarvoor wordt WSL2 gebruikt. Tegen kwaadaardige code is ze geen volledige grens. Voor sterke isolatie zijn containers of virtuele machines de betere keuze.

Vijf beschermingslagen van startlocatie via rechten, hooks en sandbox tot een wegwerpomgeving
Beschermingslagen tegen vreemde instructiebestanden.

Netwerk-allowlist en wegwerpomgeving

Een dergelijke allowlist had het downloaden van het pakket en de omleiding van de API bemoeilijkt. Dat is een duiding, geen bewijs voor dit geval. Onbekende code hoort in een wegwerpomgeving: container, VM of dev container, zonder de inloggegevens van het hoofdprofiel. Tokens moeten een korte levensduur hebben. Bij een vermoeden wordt aangeraden het aanmeldtoken als gelekt te beschouwen en te vernieuwen.

Browserinstelling voor downloads

Tegen stille downloads helpt de instelling om vóór elke opslag naar de locatie te vragen. In Chrome heet die "Vragen waar elk bestand moet worden opgeslagen voordat je het downloadt" en staat ze in de instellingen onder Downloads. Edge en Firefox bieden iets vergelijkbaars, de benamingen verschillen per versie (Firefox: Instellingen, Algemeen, Bestanden en toepassingen). Brave vroeg in de test van BleepingComputer uit zichzelf om bevestiging. Als alternatief kan de downloadmap op een plek worden gezet die nooit als werkmap dient. Een shell-alias of een hook die het starten in ~/Downloads weigert, is een extra optie.

Checklist voor teams en richtlijn voor het gebruik van codeeragents

De volgende lijst vat de maatregelen samen. Ze vult de aanbevelingen uit de twee berichten aan met de configuraties uit de documentatie van de leveranciers.

  • Agents worden alleen gestart in de hoofdmap van een vertrouwde repository. Downloads, Bureaublad en de thuismap zijn taboe.
  • Vreemde bestanden zoals AGENTS.md, CLAUDE.md of .cursor/rules worden gelezen voordat een vers gekloond of uitgepakt project wordt geopend.
  • Rechtenvragen en sandbox blijven actief. Automatische modi en vlaggen zoals –yolo draaien alleen in geïsoleerde omgevingen.
  • Netwerktoegang loopt via een allowlist, inloggegevens liggen buiten bereik, tokens hebben een korte levensduur.
  • Pakketinstallaties door agents gebeuren alleen na goedkeuring, met lockfile en controle van de registry. Hoe snel een pakket andere pakketten binnenhaalt, laat het geval met function-color en function-flag zien.
  • Instellingen worden centraal beheerd. Wijzigingen aan ~/.codex/config.toml en .claude/settings.json worden bewaakt.
  • Geladen instructiebestanden worden vastgelegd, voor zover de tools dat toelaten.
  • Incidentplan: sessie stoppen, tokens en sleutels vernieuwen, configuratiebestanden controleren, pakketinstallaties herleiden.

Organisaties met verplichtingen op het gebied van informatiebeveiliging nemen zulke agents op in hun risicobeheer. Dat betreft de toestemming, de configuratie en het bewijs dat de regels gelden. Een artikel over agentic coding beschrijft hoe het gebruik in ontwikkelteams kan worden georganiseerd.

Modelrichtlijn

Een beknopte richtlijn is in enkele zinnen te formuleren. Het toepassingsgebied omvat alle medewerkers en dienstverleners die AI-codeeragents gebruiken op apparaten van het bedrijf of met bedrijfsgegevens. Agents worden alleen gestart in de hoofdmap van een gecontroleerde repository, nooit in de mappen Downloads, Bureaublad of de thuismap. Automatische modi en het uitschakelen van sandbox of goedkeuringen zijn alleen toegestaan in geïsoleerde wegwerpomgevingen zonder inloggegevens. Pakketinstallaties en wijzigingen aan configuratiebestanden vereisen goedkeuring door de ontwikkelaars. Verantwoordelijk voor de centrale instellingen is de afdeling IT-beveiliging, voor de naleving in het project de projectleiding. Vermoedelijke incidenten worden direct gemeld bij IT-beveiliging, getroffen tokens worden onmiddellijk vernieuwd.

Eigen websites en systemen controleren

Het geval betreft vooral computers van ontwikkelaars. Wie zelf bestanden ter download aanbiedt, is met de eigen website deel van de keten. Een websitecheck laat zien welke scripts en headers een pagina uitlevert, maar controleert alleen de pagina, niet de computer van ontwikkelaars. Voor een systematische beveiligingscontrole in teams bieden de Web Security Checks een startpunt.

Conclusie

De verantwoordelijkheid ligt bij de gebruiker, de techniek trekt de grens!

Een vreemd tekstbestand kan een codeeragent sturen, omdat de agent bestanden in de werkmap als instructies behandelt. Betrouwbaar wordt de bescherming pas door afgedwongen grenzen: rechten, hooks, sandbox, netwerk-allowlist en centraal beheerde instellingen.

Open blijft of aanvallers de route via browserdownloads in de praktijk gebruiken en hoe het bestand bij de klant terechtkwam. Belangrijk lijkt in elk geval de bewustwording van medewerkers en ontwikkelaars (totdat ze uitsterven).

About the author on dr-dsgvo.de
My name is Klaus Meffert. I have a doctorate in computer science and have been working professionally and practically with information technology for over 30 years. I also work as an expert in IT & data protection. I achieve my results by looking at technology and law. This seems absolutely essential to me when it comes to digital data protection. My company, IT Logic GmbH, also offers consulting and development of optimized and secure AI solutions.

Schreiben Sie einen Kommentar

Ihre Mail-Adresse wird nicht veröffentlicht.

Eerste datalek met AI-agent gemeld: wat art. 33 AVG vereist