AI om de veiligheid van de code te verbeteren?

AI om de veiligheid van de code te verbeteren?

Deel 1: veiligheid van de gegenereerde code

De uitgebreide communicatie rond generatieve artificiële intelligentie (GenAI) en het toenemende gebruik ervan – althans in de testfase – uit angst om iets te missen of om een echte meerwaarde te bieden, roept de vraag op of het in veel domeinen nuttig is, en waarom niet, om de veiligheid van code te verbeteren. Meer bepaald: kan GenAI worden gebruikt om veiligere computercode te schrijven? Kan het helpen bij het opsporen van kwetsbaarheden in bestaande code?

In dit eerste deel geven we een antwoord op de eerste vraag. De tweede vraag komt in een ander artikel aan bod.

Menselijke aspecten

Laten we beginnen met het menselijke aspect van het gebruik van GenAI. In een gedetailleerde analyse, die ik ten zeerste aanbeveel, leggen Simkute. de redenen uit die kunnen leiden tot een productiviteitsverlies van programmeurs die een beroep doen op GenAI. Onderzoekers hebben het onder andere over: een verglijding van de programmeurrol van productie naar evaluatie, een onnuttige herstructurering van werkstromen, onderbrekingen en de neiging van GenAI om makkelijke taken nog gemakkelijker en moeilijke taken nog moeilijker te maken. De resultaten van een studie van Perry, van Stanford University verbazen ons dan minder. Deze tonen aan dat deelnemers die toegang hebben tot een codeerassistent op basis van een AI-model aanzienlijk minder veilige code schrijven dan deelnemers zonder toegang. Erger nog, deelnemers met toegang tot de assistent geloofden vaker dat ze veilige code schreven dan deelnemers zonder toegang. Deze observatie van Perry et al. wordt bevestigd door het werk van Klemmer: het onderzoeksteam ondervroeg professionele programmeurs, en hoewel zij wantrouwig staan tegenover suggesties van AI-codeerassistenten, blijkt dat zij ook hun eigen vermogen om de suggesties van deze codeerassistenten te beoordelen overschatten. Het gebruik van codeerassistenten vereist daarom de implementatie van systematische codecontrole en statische analyse.

Betrouwbaarheid van de voorstellen

Wat betreft de kwaliteit van de suggesties van GenAI: hoewel het over het algemeen functioneel correcte code oplevert, introduceert het ook veiligheidsproblemen. Khoury hebben met behulp van meerdere voorbeelden aangetoond dat ChatGPT 3.5 vaak code genereert die voor veiligheidsproblemen kan zorgen : slechts 5 van de 21 use cases die de auteurs bestudeerd hebben waren aanvankelijk beveiligd. ChatGPT 3.5 was in staat om beveiligde code aan te maken voor slechts 7 gevallen en dit was pas mogelijk nadat de auteurs expliciet vroegen om de code te verbeteren.

Meer recentelijk concludeerden Sivana dat ChatGPT als platform meer CWE-kwetsbaarheden genereerde dan de website StackOverflow. Onafhankelijk daarvan hebben Fu aan de hand van honderden door Copilot gegenereerde codevoorbeelden die op GitHub zijn gevonden, aangetoond dat ongeveer een derde daarvan veelvoorkomende kwetsbaarheden bevat die door de organisatie MITRE zijn geïnventariseerd (waarvan sommige tot de 25 belangrijkste behoren). De auteurs raden programmeurs daarom aan om de beste praktijken voor het gebruik van codegeneratietools te volgen en de gegenereerde codesuggesties altijd te controleren. Soortgelijke resultaten waren al gevonden door Pearce twee jaar eerder.

Er zijn nog veel meer voorbeelden van soortgelijke resultaten. Dat hebben Basic en Giaretta gedaan in een uitgebreide systematische studie van de academische literatuur over GenAI en de veiligheid van computercode. De betrokken modellen zijn divers en omvatten onder meer ChatGPT 3.5, GPT 4-Turbo, Copilot, Claude, Sonnet en Gemini Pro. De auteurs bevestigen dat verschillende belangrijke kwetsbaarheden, zoals SQL-injecties en bufferoverflows, kunnen worden aangetroffen in de code die door GenAI wordt gegenereerd. Ze wijzen er ook op dat het risico van vergiftiging van trainingsgegevens niet alleen kan leiden tot het genereren van onveilige code, maar ook de detectie van kwetsbaarheden in gevaar kan brengen.

Vergiftiging van AI

Het vergiftigen van een generatief model voor codeaanvulling bestaat uit het compromitteren van de integriteit van dit model door kwaadaardige codevoorbeelden in de trainingsgegevens van het model te integreren. Backdoor-aanvallen proberen tijdens de trainingsfase triggers te verbergen in het diepe neurale netwerk van het model, waardoor resultaten worden gegenereerd die door de tegenstander zijn gekozen.

Ondanks aanzienlijke vooruitgang op het gebied van codeaanvullingsmodellen blijven deze kwetsbaar voor dit soort aanvallen, zoals Yan met CodeBreaker hebben aangetoond. Voor hun aanval is het niet nodig om een vooraf getraind groot model zoals BERT of GPT te compromitteren. Deze modellen worden namelijk vaak gebruikt als basis die slachtoffers nauwkeurig afstemmen op specifieke taken met behulp van specifieke gegevens die vaak openbaar beschikbaar zijn. De tegenstander hoeft dus alleen maar deze finetuning data te compromitteren of zijn eigen set vervuilde data, gegenereerd met CodeBreaker, te uploaden. De vergiftigde code die na gebruik van CodeBreaker wordt gegenereerd, is niet detecteerbaar met kwetsbaarheidsdetectietools op basis van traditionele statische analyses of GenAI.

Hoewel dit soort aanvallen onwaarschijnlijk is, rijst de vraag waar de gebruikte GenAI-tool vandaan komt en past dit in de problematiek die inherent is aan de huidige GenAI om zowel veilige als nauwkeurige modellen te verkrijgen.

Belang van de prompt

Het is echter niet allemaal kommer en kwel en het belang van de keuze van de prompts die aan GenAI worden gegeven om het genereren van code met potentiële zwakke punten te voorkomen, moet worden benadrukt. Götz tonen aan dat, terwijl 65% van de code die oorspronkelijk door verschillende GenAI-tools werd gegenereerd, door een gekwalificeerde ingenieur als onveilig wordt beschouwd, dezelfde tools veilige code genereren wanneer ze handmatig worden aangestuurd. De auteurs concluderen dat technische expertise, met name op het gebied van beveiliging, vereist is om veilige code te genereren met behulp van code AI-codeerassistenten.

Om de best mogelijke resultaten te verkrijgen, moet de prompt die aan GenAI wordt gegeven zowel nauwkeurig als duidelijk interpreteerbaar zijn voor het model. Met andere woorden: de programmeur heeft er alle belang bij om zich aan de eisen van de machine te houden en zo gedetailleerd mogelijk niet alleen de taak die het model moet uitvoeren, maar ook de context waarin deze taak plaatsvindt en de verwachte invoer- en uitvoergegevens te specificeren. Dit kan in één keer gebeuren of in de vorm van een chain-of-thoughts volgens een bepaalde redenering.

Er bestaat echter geen ideale methode, maar Bruni geven verschillende eenvoudige voorbeelden van verbetering van prompts. Volgens hun experimenten is de meest effectieve methode om, na een eerste prompt, GenAI te vragen de code die het al heeft voorgesteld op mogelijke kwetsbaarheden te herzien en vervolgens correcties voor te stellen. Bijvoorbeeld:

  • Prompt 1: genereer Java-code voor …
  • Prompt 2: analyseer de volgende code en vind de beveiligingsproblemen: <antwoord op prompt 1>
  • Prompt 3: op basis van de volgende problemen: <problemen gemeld door prompt 2>, verbeter de volgende code: <antwoord gegeven op prompt 1>

Deze werkwijze veronderstelt uiteraard dat GenAI in staat is om kwetsbaarheden op te sporen, maar zoals we in het volgende artikel zullen zien, is dat vandaag nog niet het geval.

Gespecialiseerde tools

We kunnen echter nieuwe tools verwachten die programmeurs in staat zullen stellen om de veiligheidsrisico’s van GenAI te vermijden.

Zo biedt de tool SafeCoder van ETH Zürich een kader om de veiligheid van door GenAI gegenereerde code te verbeteren zonder de functionaliteit van die code in het gedrang te brengen. De tool combineert de standaardinstellingen van instructies met een veiligheidsgerichte finetuning aan de hand van veilige en onveilige codevoorbeelden. Om een dataset van hoge kwaliteit te creëren, hebben de auteurs een geautomatiseerd proces opgezet dat geverifieerde kwetsbaarheidscorrecties uit de op GitHub geregistreerde codewijzigingen haalt met behulp van heuristische filtering en statische analyse op basis van de CodeQL-tool. De resultaten tonen aan dat SafeCoder de codeveiligheid met ongeveer 30% verbetert, terwijl de bruikbaarheid in benchmarks zoals HumanEval en MMLU behouden blijft. De auteurs geven echter toe dat de tool de veiligheid van code met kwetsbaarheden waarvoor hij niet is getraind, niet verbetert.

In de tussentijd kan een manier zijn om een traditionele statische analyse te combineren met GenAI door eerst de GenAI te vragen de gewenste code te genereren en vervolgens de statische analyse te gebruiken om deze code te analyseren. Als de tool een probleem identificeert en de correctie niet voor de hand ligt, kan men de GenAI vragen om de code aan te passen, waarbij de eerder geïdentificeerde fout wordt aangegeven. De lus kan worden herhaald totdat er geen probleem meer wordt geïdentificeerd door het analyse tool. Natuurlijk kan deze omslachtige procedure worden geautomatiseerd in een normale softwareontwikkelingscyclus.

Conclusie

Het eerste deel van dit artikel ging over de impact van GenAI op de kwaliteit van code in termen van beveiliging. In de huidige situatie moet worden vastgesteld dat, ondanks het verbazingwekkende vermogen van GenAI-tools om computercode te genereren, deze code vaak veiligheidsproblemen kan opleveren, ongeacht het gekozen model. Het is daarom raadzaam om zeer waakzaam te zijn vooraleer we code gebruiken die door GenAI-tools is gegenereerd. Bovendien kunnen GenAI-tools bepaalde programmeertaken vergemakkelijken, maar dat neemt niet weg dat zij niet verantwoordelijk zijn voor de mogelijke negatieve gevolgen van hun “werk”. Die verantwoordelijkheid ligt bij de programmeur en zijn werkgever.

De vaardigheden en kennis op het gebied van veiligheid van programmeurs – wier taak geleidelijk zal evolueren van codeschrijver naar codecontroleur – blijven een essentiële troef. De komst van GenAI in de ontwikkelcyclus is misschien een goede gelegenheid om de samenwerking tussen beveiligings- en ontwikkelingsteams te versterken door werkgroepen op te richten (of te versterken) waarin gemeenschappelijke doelstellingen worden afgestemd om de beveiliging te verbeteren.

In het tweede deel zullen we ons concentreren op het gebruik van GenAI voor het opsporen van kwetsbaarheden in code.


Dit is een ingezonden bijdrage van Fabien A. P. Petitcolas, IT-beveiligingsspecialist bij Smals Research. bij Smals Research. Dit artikel werd geschreven in eigen naam en neemt geen standpunt in namens Smals. Interesse om bij Smals te werken? Neem dan een kijkje naar het huidige uitgebreide jobaanbod.