Veiligheid & grenzen
Promptinjectie bij AI-agents: filters falen, actiegrenzen werken
Promptinjectie bij AI-agents: waarom aanvalscijfers zo uiteenlopen, wat een grens rond risicovolle handelingen oplevert, en wat die kost.
De OWASP GenAI/LLM Top 10 zet promptinjectie al twee edities op nummer één. In de voorrede van de editie van augustus 2026 staat een zin die je daar niet verwacht: rangschik je de categorieën op het ruwe incidentregister, dan valt promptinjectie buiten de top tien.
Dat is geen slordigheid maar een keuze die ze uitleggen. De eindpositie weegt voor driekwart de stem van practitioners en voor een kwart de incidentdata. Die incidentdata is een corpus van 7.714 gemelde incidenten, waarvan er 6.639 genoeg detail hadden om door hun classificeerders ingedeeld te worden — cijfers die in het voorwoord bij de lijst staan, niet in de entry over promptinjectie zelf. Hun verklaring voor het gat is dat de verdediging werkt en het daardoor niet in de incidenten opduikt; ze presenteren dat als uitleg, niet als bevinding.
Het risico dat het zwaarst weegt in het oordeel van bouwers, weegt het lichtst in de cijfers. Dat verschil is niet het onderwerp van dit stuk, maar het is wel de reden dat de cijfers eromheen zo lastig te lezen zijn.
Waartegen dit stuk beschermt
“Promptinjectie” dekt een aantal verschillende dreigingen, en de bronnen hieronder gaan niet over dezelfde. Het loont om te zeggen welke hier bedoeld wordt:
- Een kwaadwillende gebruiker — iemand met legitieme toegang die het systeem iets laat doen wat niet mag. Dat is een autorisatievraagstuk en valt hier buiten.
- Onvertrouwde inhoud die de agent inleest — een issue, een pagina, een bestand, de uitvoer van een tool, metadata van een dependency. Hier gaat dit stuk over.
- Een gecompromitteerde dependency — overlapt hiermee, want de metadata en de uitvoer ervan komen in dezelfde context terecht, maar de verdediging ertegen is grotendeels een andere.
- Modelgedrag zonder aanvaller — een agent die uit zichzelf iets onhandigs doet. Verrassend genoeg loopt de oplossing daarvoor grotendeels gelijk op met die voor het tweede punt, en dat is geen toeval: allebei gaan ze over wat een agent mag uitvoeren als je z'n oordeel niet vertrouwt.
De vraag die overblijft is dus smal en concreet: onvertrouwde inhoud die via de agentcontext invloed probeert uit te oefenen op handelingen met een extern gevolg.
Waarom filteren geen sluitende laag is
De voor de hand liggende verdediging is: leer het systeem het verschil tussen data en instructie. Abdelnabi en Bagdasarian (mei 2026) betogen dat die aanpak twee dingen tegelijk misdoet: hij mist aanvallen die via contextuele manipulatie werken, én hij beschadigt gedrag dat contextueel juist wél passend is.
Hun argument herformuleert promptinjectie via Contextual Integrity, een privacytheorie die beoordeelt of een informatiestroom past bij de context waarin die plaatsvindt. De uitkomst noemen ze zelf een onmogelijkheidsargument, en de formulering is belangrijk: “We argue, informally, that no fixed policy can prevent all context-based attacks without also blocking some legitimate flows.” Geen stelling, geen bewijs — een beredeneerd argument, in een sectie die letterlijk “An Impossibility Argument” heet.
Twee metingen die dat argument onderbouwen:
Dat tweede getal is het ongemakkelijke. SecAlign is met DPO getraind om promptinjectie te weerstaan en verstuurt vaker dan een onbehandeld model. De auteurs opperen een verklaring — de training onderdrukte reacties op syntactische injectiepatronen, of nam een simpeler dreigingsmodel aan dat botst met voorwaardelijke toestemmingen — maar meten die verklaring niet.
Wat hier níét staat
Niet dat filteren waardeloos is. Een filter dat de goedkope, ongerichte pogingen wegvangt, doet werk dat een duurdere laag anders zou moeten doen. Wat er staat is smaller: filteren is geen betrouwbare vervanging van een controle rond de handeling, want het adresseert een andere vraag. En de afruil die de auteurs beschrijven geldt volgens hen voor “a fully autonomous agent” — over opstellingen waarin een mens verplicht tussenkomt doet dit argument in deze vorm geen uitspraak.
Waarom aanvalssuccespercentages zo uiteenlopen
Wie de literatuur naast elkaar legt, ziet cijfers die niet bij elkaar lijken te horen. Op één plek slaagt 96,7% van de aanvallen, op een andere 4,7%. De verleiding is om er een winnaar uit te kiezen. Dat is de verkeerde beweging: het zijn metingen aan verschillende dingen.
Hofer, Debenedetti en Tramèr (juni 2026) meten geautomatiseerde optimalisatie: procedures die zelf naar een werkende injectie zoeken, binnen AgentDojo, over 80 taakparen in vier domeinen.
Die derde kolom is de interessantste. Per losse poging blijft GPT-5 op 4,7%; over vier onafhankelijke pogingen valt 30,0% van de taakparen. Hetzelfde model, dezelfde aanval, een factor zes verschil — alleen door te herhalen.
Abdelnabi en Bagdasarian meten iets anders: een semantisch geïnformeerde lus die de context zelf herschrijft — een afzender claimen, een norm oproepen, twee stromen door elkaar mengen. Die haalt 96,7% tegenover een basislijn van 0,67%, en in 61,4% van de gevallen slaagt al de eerste poging. De auteurs zetten er zelf een rem op: die cijfers zijn uitdrukkelijk bedoeld als kwalitatieve verkenning en niet als definitieve kwantitatieve analyse, omdat hun geautomatiseerde aanvaller z'n eigen randvoorwaarden niet betrouwbaar respecteerde.
Wat daaruit volgt
Een aanvalssuccespercentage is geen eigenschap van promptinjectie. Het is een eigenschap van één combinatie van model, aanvalsmethode, dreigingsmodel, taak, aantal pogingen, toolset, agentarchitectuur, beschikbare rechten en evaluatieprocedure. Verander er één, en het getal beweegt met een orde van grootte.
Praktisch gevolg: twee getallen uit twee papers mag je niet naast elkaar zetten alsof ze hetzelfde meten, en een laag percentage in een benchmark zegt weinig over jouw opstelling. Wat wél overdraagbaar is, is de vorm van de bevinding — herhaling helpt de aanvaller, semantiek helpt meer dan tokenoptimalisatie, en een sterker model verlegt de drempel zonder hem weg te nemen.
Wat er nog meer in die meting zit, en waar de auteurs zelf op wijzen
Zwart-doosoptimalisatie (TAP) verslaat gradiënt-gebaseerde optimalisatie (GCG) ruim; de auteurs vermoeden dat GCG's tokenniveau-zoektocht instabiel is binnen een redelijk rekenbudget. GCG-suffixen die op open modellen zijn geoptimaliseerd halen tegen GPT-5 minder dan 1% — overdracht over modelfamilies heen is een echte drempel.
Maar die drempel is met één bronmodel gemeten. De auteurs schrijven er zelf bij dat gezamenlijke optimalisatie over meerdere bronmodellen de overdracht kan verhogen, en dat GPT-5 gekozen is als representant van de frontier “at the time of the experiments”. Of het gat blijft bestaan noemen ze een open vraag.
Wat telt als een risicovolle handeling, en wat niet
De rest van dit stuk draait om één onderscheid, en het loont om het expliciet te maken. Niet elke uitvoer van een model heeft dezelfde grens nodig.
- Handelingen met een extern of blijvend gevolg — code samenvoegen, een bericht versturen, een bestand verwijderen, een credential gebruiken, productie wijzigen, een betaling doen, een permissie aanpassen. Hier gaat het om.
- Handelingen die binnen de sessie blijven — tekst samenvatten, classificeren, informatie ophalen, een concept schrijven dat nog nergens heen gaat. Fout gaan kost hier tijd, geen toestand.
Dat onderscheid is niet netjes en niet binair — een samenvatting die een mens misleidt heeft ook gevolgen, en een agent die alleen leest kan nog steeds gegevens naar buiten dragen. Maar het is bruikbaar genoeg om de vraag te stellen die ertoe doet: wat gebeurt er als deze handeling verkeerd uitpakt, en hoe moeilijk is dat terug te draaien?
De grens hoort rond de handeling
Als je de invoer niet betrouwbaar kunt keuren, blijft er één plek over waar een controle iets kan betekenen: tussen het voorstel en de uitvoering. Het verschil zit er niet in dat de ene laag beter is dan de andere — het zit erin dat ze op een andere plek in de keten staan.
CaMeL, ontwerppatronen en ActPlane doen niet hetzelfde
Drie bronnen wijzen dezelfde kant op, en het is verleidelijk ze als één maatregel te lezen. Ze werken op verschillende lagen en lossen verschillende delen op.
- CaMeL (Google DeepMind, 2025) haalt de control- en dataflow uit de gebruikersvraag, zodat onvertrouwde data de programmastroom niet kan wijzigen, en dwingt beleid buiten het model af. Op AgentDojo lost de best presterende opstelling 77% van de taken op tegen 84% onverdedigd; over de gerapporteerde modellen heen loopt het nutverlies uiteen van 3,1 tot 32,0 procentpunt.
- De ontwerppatronen (Beurer-Kellner et al., 2025) zijn geen systeem maar zes architecturale vormen — action-selector, plan-then-execute, LLM map-reduce, dual LLM, code-then-execute, context-minimization — die vertrouwde besturingsstroom en onvertrouwde data uit elkaar houden. Er staat geen enkele meting in de lopende tekst; het is een ontwerpcatalogus met tien uitgewerkte casussen.
- ActPlane (juni 2026) zakt naar het besturingssysteem: handhaving via eBPF op de syscalls die een agentharnas uitvoert. Op de 114 traces waarin de agent daadwerkelijk beleid schond, detecteert het 77,2% van de overtredingen, waar promptfilters, tool-regex en FIDES op 34 tot 40% blijven.
Wat daaruit volgt
Deze drie zijn geen varianten van één verdediging. Wat ze delen is smaller en interessanter: geen van drieën maakt het model beter in oordelen, en alle drie zorgen ze dat het gevolg niet enkel afhangt van de interpretatie van het model. Dat is de overdraagbare eigenschap — niet de laag waarop ze hem realiseren.
Elk van de drie noemt zijn eigen rekening
CaMeL vraagt van de gebruiker dat die het beleid zelf opschrijft en onderhoudt, en de auteurs waarschuwen voor waarschuwingsmoeheid: wie te vaak om goedkeuring wordt gevraagd, klikt uiteindelijk door. De ontwerppatronen perken de agent bewust in — “These patterns impose intentional constraints on agents, explicitly limiting their ability to perform arbitrary tasks” — en in hun SQL-casus verliest de agent het vermogen om te beoordelen of de opgehaalde data de vraag beantwoordt. ActPlane activeert op 16% van de taken die zonder handhaving al veilig waren, en de gerapporteerde overhead van 1,9 tot 8,4% is gemeten met regels die geladen zijn maar niet afgaan.
Wat de leverancier zelf zegt
De beveiligingspagina van Claude Code (laatst gewijzigd 21 augustus 2026) is opvallend bescheiden voor een productpagina. Er staat geen enkel effectiviteitscijfer op. Wat er wel staat is de zin “no system is completely immune to all attacks”, een opsomming van maatregelen die grotendeels in Manual mode gelden, en een waarschuwing die één concrete omzeiling van het eigen toestemmingssysteem benoemt. In auto mode neemt een classifier een deel van de beoordeling over, terwijl expliciete ask- en deny-regels blijven gelden. De waarschuwing: WebDAV op Windows kan netwerkverzoeken naar externe hosts uitlokken buiten dat toestemmingssysteem om.
De pagina belooft risicoreductie en geen bescherming, en legt de laatste beoordeling expliciet bij de gebruiker. Dat is dezelfde uitkomst als het onderzoek, alleen zachter geformuleerd.
Vanaf hier: mijn ontwerpinterpretatie
Alles hierboven is terug te lezen in de bronnen onderaan, en waar ik synthetiseerde stond dat als “wat daaruit volgt” gemarkeerd. Wat nu volgt is van geen van beide soorten: het zijn de conclusies die ik voor mijn eigen bouwwerk trek. Neem ze als voorstel.
Wat ik hieruit zou bouwen
- Vraag niet of je systeem te misleiden is. Het antwoord is bekend en het brengt je nergens. De bruikbare vraag is wat er dan kan gebeuren, en wie dat tegenhoudt.
- Weeg de controle tegen het gevolg. Een samenvatting laten mislukken kost tijd; een merge laten mislukken kost toestand. Dat verschil hoort in de opstelling terug te komen, en niet in een algemene regel die alles dichttimmert.
- Laat onzekerheid niet vanzelf tot uitvoering leiden bij zware handelingen. Voor een leesactie is doorlaten prima. Voor een merge is “ik weet het niet” hetzelfde als “dit mag niet”.
- Houd de beleidslaag buiten het bereik van de data die hij beoordeelt. Dit is een architecturale gevolgtrekking van mij, geen bevinding uit deze papers. De redenering: een controle die meegewijzigd kan worden door de stroom die hij moet beoordelen, is onderdeel van die stroom geworden. Waar dat feitelijk zit — in een andere repository, achter een ander recht, in een ander proces — verschilt per systeem, en het is het lastigste deel om waar te maken.
- Reken op herhaling, niet op één poging. Het verschil tussen 4,7% en 30,0% bij vier pogingen is het verschil tussen “dat lukt bijna niet” en “dat lukt een derde van de tijd”.
- Noem de prijs. Elke bron hier benoemt wat de grens aan bruikbaarheid kost. Een voorstel dat dat niet doet, is nog niet af.
Dat laatste uitgeschreven, want “fail closed” als algemene regel levert een systeem op dat bij elke twijfel stilstaat. Wat onzekerheid zou moeten doen, hangt af van wat er misgaat als het toch doorgaat:
- Samenvatten of classificeren — laat het door. Fout gaan kost tijd.
- Code schrijven in een geïsoleerde omgeving — laat het door, mits de isolatie er echt is.
- Een PR openen — laat het door onder beleid; er staat nog een poort achter.
- Mergen, publiceren, verwijderen, betalen — houd het tegen, of stuur het naar een mens.
Wat dit onderzoek niet aantoont
- Niet dat invoerfilters waardeloos zijn — ze vangen de goedkope pogingen weg.
- Niet dat elke agent een mens in de lus nodig heeft. Dat hangt af van wat de agent kan uitvoeren.
- Niet dat handhaving op kernelniveau nodig is. ActPlane laat zien dát het kan, niet dat het moet.
- Niet dat één architectuur promptinjectie oplost. Geen van de bronnen claimt dat.
- Niet dat aanvalssuccespercentages tussen papers vergelijkbaar zijn. Dat is precies de fout die deze sectie probeert te voorkomen.
Waar het ophoudt
Vier voorbehouden bij deze zeven bronnen
Vijf van de zeven zijn preprints. Geen van de arXiv-stukken hier is onafhankelijk gerepliceerd, en drie zijn van de afgelopen drie maanden. Voor een veld dat zo snel beweegt is dat het beste wat er is, en het is minder dan je zou willen.
De benchmarks zijn klein en deels zelfgebouwd. 80 taakparen bij Hofer en collega's, 190 traces bij ActPlane waarvan 114 met een echte overtreding, en bij Abdelnabi en Bagdasarian sets die met een taalmodel zijn gegenereerd en handmatig gevalideerd. Dat is geen diskwalificatie — er is niets beters — maar het is ook geen veldmeting.
Er zit een interne tegenspraak in het CaMeL-artikel. De lopende tekst noemt een daling van 300 naar 0 geslaagde aanvallen voor één model; Tabel 4 van hetzelfde artikel geeft voor dat model 163. Ik heb dat getal daarom niet gebruikt. In dezelfde vergelijking waar CaMeL op veiligheid wint, verliest het op bruikbaarheid van de eenvoudiger verdedigingen ernaast.
De OWASP-cijfers komen uit het voorwoord. Het corpus van 7.714, de 6.639 geclassificeerde incidenten en de 75-25-weging staan in LLM00_Preface, niet in de entry LLM01. De entry zelf bevat geen corpuscijfer. Wie ze citeert hoort de juiste vindplaats te noemen.
Toets het op je eigen systeem
Laat je eigen systeem uitzoeken welke van zijn handelingen onomkeerbaar zijn, en of de beslissing om ze toe te staan afhangt van tekst die het systeem heeft ingelezen.
Je gaat de grens van dit systeem in kaart brengen. Niet of het te misleiden is — dat is een aanname waar je niets aan hebt — maar wat er dan kán gebeuren, en wie dat tegenhoudt. Stap 1 — inventariseer de consequential actions. Welke acties kan dit systeem uitvoeren met een extern of blijvend gevolg? Denk aan: schrijven naar een externe bestemming, een bericht versturen, code samenvoegen, een bestand verwijderen, een credential gebruiken, productie wijzigen, een permissie aanpassen. Zet er de acties naast die dat níét zijn — samenvatten, classificeren, opzoeken — want die hebben een andere grens nodig. Noem per actie waar in de code hij vandaan komt. Stap 2 — volg de invoer. Voor elke consequential action: welke tekst kan het systeem gelezen hebben voordat het besluit? Onderscheid scherp tussen tekst die de opdrachtgever zelf schreef en tekst die van elders komt — een issue, een pagina, een bestand, een zoekresultaat, de uitvoer van een tool, metadata van een dependency. Alleen dat tweede is aanvalsoppervlak. Stap 3 — zoek de beslisser. Wie besluit uiteindelijk dat de handeling doorgaat: het model, of iets buiten het model? Als het antwoord "het model, op grond van wat het gelezen heeft" is, noteer dat als bevinding en niet als ontwerp. Zit er wél een controle buiten het model, beantwoord dan deze vier: a) kan die controle bereikt worden door de tekst die hij moet beoordelen? b) wat doet hij als hij het niet weet — doorlaten of tegenhouden? c) kan een wijziging die het systeem zelf voorstelt de controle verzwakken? d) draait de controle vanaf code die in dezelfde wijziging kan zitten? Wijs aan waar dat staat; een opmerking in een bestand is geen bewijs. Stap 4 — weeg de controle tegen het gevolg. Niet elke handeling verdient dezelfde grens. Geef per actie aan wat onzekerheid zou moeten doen: doorlaten, isoleren, of tegenhouden. Motiveer dat met de omkeerbaarheid en de reikwijdte, niet met een algemene regel. Stap 5 — benoem de prijs. Elke grens kost iets aan bruikbaarheid. Zeg voor je voorstel wat er daarna niet meer vanzelf gaat, en of dat het waard is. Een aanbeveling zonder prijskaartje is geen aanbeveling. Stap 6 — zeg wat je niet kunt vaststellen zonder te meten, en welke test je zou draaien om het wél te weten.
Bronnen
- AI Agents May Always Fall for Prompt InjectionsAbdelnabi & Bagdasarian · arXiv:2605.17634 [cs.CR], ingediend 17 mei 2026 · 2026
- Assessing Automated Prompt Injection Attacks in Agentic EnvironmentsHofer, Debenedetti & Tramèr (ETH Zürich) · arXiv:2606.10525 [cs.CR], DOI 10.48550/arXiv.2606.10525 · 2026
- Defeating Prompt Injections by Design (CaMeL)Debenedetti et al. (Google DeepMind) · arXiv:2503.18813 [cs.CR], v2 van 24 juni 2025 · 2025
- Design Patterns for Securing LLM Agents against Prompt InjectionsBeurer-Kellner et al., veertien auteurs uit tien instellingen · arXiv:2506.08837 [cs.LG], v3 van 27 juni 2025 · 2025
- ActPlane: Programmable OS-Level Policy Enforcement for Agent HarnessesZheng et al. · arXiv:2606.25189 [cs.OS], v2 van 30 juni 2026 · 2026
- OWASP GenAI/LLM Top 10 2026 — LLM01 Prompt Injection en LLM00 PrefaceOWASP GenAI Security Project · OWASP Foundation, editie van 4 augustus 2026 · 2026
- Security — Claude CodeAnthropic · Officiële documentatie, laatst gewijzigd 21 augustus 2026 · 2026