- Laten zoeken naar kwetsbaarheden in je hele project, ook in code die je zelf niet meer overziet.
- Laten uitleggen waarom iets een risico is, in gewone taal, zodat je begrijpt wat je repareert.
- Laten voorstellen wat een oplossingsrichting zou zijn, als vertrekpunt voor je eigen werk.
- Laten schrijven van tests die aantonen dat het gat er is, want die kun je zelf controleren door ze te draaien.
Mag je AI je beveiligingsfouten laten repareren?
AI is opvallend goed in het vinden van beveiligingsfouten en opvallend matig in het oplossen ervan. Uit onderzoek dat deze maand rondging blijkt ongeveer de helft van de door AI voorgestelde patches zelf kwetsbaarheden te bevatten. Microsoft stelde om vergelijkbare redenen een grote Exchange-update uit, omdat door AI aangedragen bevindingen handmatig geverifieerd moesten worden. Hieronder hoe je die scheiding praktisch aanhoudt.
Waarom vinden makkelijker is dan repareren
Het verschil zit in wat er nodig is om het goed te doen.
Een beveiligingsfout vinden is grotendeels patroonherkenning. Invoer die niet wordt gecontroleerd, een vergelijking die op de verkeerde manier gebeurt, een sleutel die in de code staat, een rechtencontrole die op één plek ontbreekt. Dat zijn vormen die vaak voorkomen, en een model dat veel code heeft gezien is daar goed in. Het ziet ze bovendien in bestanden waar jij niet meer kijkt.
Repareren vraagt iets anders: begrijpen wat de code hoort te doen, wie hem aanroept en welke aannames de rest van het systeem maakt. Een model ziet een fragment en lost op wat het in dat fragment ziet. Het resultaat is een patch die de melding wegneemt terwijl het gat blijft, of die het gat dicht en ergens anders iets breekt.
Dat is precies het patroon in het onderzoek dat deze maand rondging: modellen zijn beter geworden in het aanwijzen van kwetsbaarheden, terwijl ongeveer de helft van de voorgestelde oplossingen zelf onveilig blijkt. Het gevaarlijke daaraan is niet de fout maar het gevoel dat het opgelost is. Datzelfde patroon zie je bij het onderhouden van door AI geschreven code, beschreven in AI-gegenereerde code onderhouden.
Waar je AI wel en niet op loslaat
De grens ligt bij de vraag of jij de uitkomst nog kunt beoordelen.
- Een voorgestelde patch overnemen zonder hem te lezen, ook niet als hij klein is.
- Automatisch laten samenvoegen wat een agent aan beveiligingsfixes oplevert.
- Een melding als opgelost afvinken omdat de scanner na de patch stil is.
- Sleutels, tokens of wachtwoorden laten roteren door iets dat je niet stap voor stap volgt.
Een werkwijze die wel klopt
Vier stappen, waarvan er twee door AI kunnen en twee niet.
Laat het model eerst zoeken en de bevindingen op een rij zetten met per stuk een uitleg van het risico. Vraag daarbij expliciet om te benoemen wat een aanvaller ermee zou kunnen, want dat scheidt echte problemen van formele opmerkingen. Deze stap is waar AI de meeste waarde levert.
Laat het vervolgens een test schrijven die het probleem aantoont. Dat is de slimste tussenstap, want een test kun je draaien en zien slagen of falen, terwijl je een patch alleen kunt beoordelen door hem te begrijpen. Faalt de test op de oude code en slaagt hij op de nieuwe, dan heb je bewijs in plaats van een gevoel.
Schrijf of beoordeel de oplossing zelf. Gebruik het voorstel van het model als startpunt maar ga na wie deze code aanroept, welke aannames er elders zijn en of de oplossing op de juiste laag zit. Een controle in de gebruikersinterface is geen oplossing als dezelfde route ook via je koppelvlak bereikbaar is.
Draai daarna je hele testset. Beveiligingspatches breken vaker iets dan gewone wijzigingen, omdat ze aan de randen van je systeem zitten. Bouw je met een agent die zelf uitvoert, houd die dan in een afgeschermde omgeving zoals beschreven in een AI-agent in een sandbox draaien, en behandel wat eruit komt als code van een onbekende.
Signalen dat een AI-patch niet deugt
Waar je op let als je een voorgestelde oplossing doorneemt.
- De patch controleert de invoer op de plek waar het probleem gemeld werd, maar niet op de plek waar de gegevens binnenkomen.
- Er wordt een controle toegevoegd in de interface terwijl dezelfde handeling ook via je koppelvlak bereikbaar is.
- Een foutmelding wordt onderdrukt in plaats van afgehandeld, waardoor de scanner stil is en het probleem blijft.
- De oplossing introduceert een nieuwe afhankelijkheid die je niet zelf hebt gekozen en niet hebt gecontroleerd.
- Er zit geen test bij, en het model kan desgevraagd niet aangeven hoe je zou merken dat het gat weer terug is.
Veelgestelde vragen
Kan AI beveiligingsfouten in mijn code vinden?
Ja, en daar is het goed in. Het herkent patronen als ongecontroleerde invoer, ontbrekende rechtencontroles of sleutels in de code, ook in bestanden waar jij zelf niet meer kijkt. Het vinden is de sterkste kant, en voor een prototype dat naar productie gaat is dit een van de nuttigste dingen die je met AI kunt doen.
Waarom zijn AI-patches zo vaak zelf onveilig?
Omdat repareren iets anders vraagt dan vinden. Het model ziet een fragment en lost op wat het daarin ziet, zonder te weten wie de code aanroept en welke aannames de rest van het systeem maakt. Uit onderzoek dat deze maand rondging blijkt ongeveer de helft van de voorgestelde patches zelf kwetsbaarheden te bevatten.
Wat als ik zelf niet genoeg van beveiliging weet om de patch te beoordelen?
Laat het model dan eerst uitleggen wat het risico is en wat een aanvaller ermee kan, en laat het een test schrijven die het probleem aantoont. Een test kun je draaien; een patch kun je alleen beoordelen door hem te begrijpen. Gaat het om iets waar klantgegevens of betalingen bij betrokken zijn, laat er dan een mens naar kijken die dit vak wel beheerst.
Mag ik een agent automatisch beveiligingsfixes laten samenvoegen?
Dat is precies de gewoonte die je niet wilt aanleren. De schade van een patch die de melding wegneemt maar het gat laat staan, is groter dan die van een openstaande melding, omdat je dan denkt dat het geregeld is. Laat elke beveiligingswijziging langs een mens, ook de kleine.
Waarom is een test schrijven de slimste tussenstap?
Omdat je daarmee van gevoel naar bewijs gaat. Een test die faalt op de oude code en slaagt op de nieuwe, laat zien dat het gat er was en nu dicht is. Zonder die test weet je alleen dat de scanner stil is, en dat kan ook betekenen dat de melding is onderdrukt in plaats van opgelost.
Betekent een stille scanner dat het opgelost is?
Niet noodzakelijk. Een veelvoorkomende uitkomst van een AI-patch is dat de vorm waarin de scanner het probleem herkende is veranderd, terwijl het onderliggende gat er nog is. Dat is een van de redenen om altijd te kijken op welke laag de oplossing zit en of de route ook langs een andere weg bereikbaar blijft.
Geldt dit ook voor afhankelijkheden die geüpdatet moeten worden?
Daar is het beeld gunstiger, want een versie ophogen is mechanisch werk waar weinig oordeel bij komt kijken. Let wel op wat er in de nieuwe versie is veranderd, en draai je testset, want juist bij updates van pakketten breekt er stilletjes iets in gedrag dat je niet had verwacht.
Wat doe ik als eerste bij een prototype dat live gaat?
Laat het hele project scannen op sleutels die in de code staan, ontbrekende rechtencontroles en ongecontroleerde invoer, en werk die lijst met de hand af. Dat is de categorie die in prototypes vrijwel altijd aanwezig is en die met afstand het meeste risico oplevert.