Eine Analyse der Code-Qualität von ChatGPT und anderen LLMs
In der Welt der Softwareentwicklung revolutionieren Large Language Models (LLMs) wie ChatGPT die Art und Weise, wie Code entwickelt wird, indem sie es Entwicklern ermöglichen, mit natürlicher Sprache Anfragen zu stellen und in sekundenschnelle generierte Code-Snippets zu erhalten. Dies verspricht eine Steigerung der Effizienz, da bei Fragen oder Problemen nicht erst Dokumentationen oder Online-Foren durchsucht werden müssen. Zusätzlich wird beworben, dass es die Zugänglichkeit der Programmierung erweitert, da Anfänger sofortiges Feedback und Beispiele erhalten können.
Im Gegensatz zu Online-Programmierforen, wie StackOverflow, in denen Code-Snippets von anderen Entwicklern analysiert, überprüft und kommentiert werden, fehlt es bei von LLMs erzeugtem Code jedoch an jeglicher Form der Peer-Überprüfung [1]. Stattdessen wird die Codegenerierung verschiedener Large-Language-Models mit Datensets wie HumanEval und MBPP miteinander verglichen. Diese Benchmarks betrachten jedoch ausschließlich die funktionale Korrektheit des erzeugten Codes und können keine Aussage darüber treffen, ob korrekter Code auch sicher und zuverlässig ist. Dies ist, insbesondere in der heutigen Zeit, in der die Zahl der Cyberangriffe stetig steigt und sich Schwachstellen in Softwareprodukten häufen [2], aber unabdinglich.
Das wirft die Frage auf: Wie qualitativ, sicher und zuverlässig ist der von Large-Language-Models generierte Code? Studien zeichnen ein dramatisches Bild.
Instabiler und unsicherer Code durch Falschverwendung von APIs
Programmierschnittstellen, bekannt als APIs (Application Programming Interfaces), sind Bausteine in der Softwareentwicklung, die es ermöglichen, dass verschiedenen Softwarekomponenten miteinander kommunizieren und Daten auszutauschen können. Häufig definieren APIs auch Regeln, wie eine vorgeschriebene Reihenfolge für Methodenaufrufe, die sicherstellt, dass die Interaktionen zwischen den Komponenten reibungslos und vorhersehbar verlaufen.
Ein prägnantes Beispiel für eine solche API ist die Java File-API, die Entwicklern eine Schnittstelle bietet, um in der Programmiersprache Java Dateioperationen durchzuführen. Diese API umfasst Methoden zum Erstellen, Öffnen, Lesen, Schreiben und Schließen von Dateien, die, wenn sie in der korrekten Reihenfolge aufgerufen werden, eine effiziente und sichere Handhabung von Dateioperationen ermöglichen.
Eine korrekte Nutzung von APIs ist für die Entwicklung sicherer, effizienter und wartbarer Software unerlässlich. Falsch eingesetzte APIs können zu einer Vielzahl von Problemen führen, die die Funktionalität, Sicherheit und Leistung der Software beeinträchtigen. Zu den möglichen Auswirkungen einer falschen API-Nutzung gehören: Datenverlust, Beschädigung des Dateisystems, Programmabsturz, Ressourcenleck, Benutzeroberflächenfehler [1].
Die Autoren des Artikels Can LLM Replace Stack Overflow? A Study on Robustness and Reliability of Large Language Model Code Generation untersuchen Large-Language-Models im Hinblick auf die korrekte Verwendung von Schnittstellen in generierten Code [1], mit erschreckenden Ergebnissen.
Die Autoren sammeln 1208 Fragen von StackOverflow, die 18 repräsentative Java-APIs betreffen. Die APIs reichen von APIs für das Input-Output Handling, über Datenbankabfragen bis zu APIs, die sich auf die Umsetzung von kryptografischen Abläufen konzentrieren. Diese Auswahl dient als Grundlage für die Evaluation der Leistungsfähigkeit der LLMs in Bezug auf die Generierung von adäquatem und korrektem Code.
Für die Experimente ziehen die Forscher sowohl geschlossene als auch offene Sprachmodelle, unter Verwendung der Standard-Hyperparameter Einstellung, heran. Konkret werden die geschlossenen Modelle GPT-3.5 und GPT-4 von OpenAI sowie die offenen Modelle Llama-2 und Vicuna-1.5 verwendet. Diese Auswahl ermöglicht einen umfassenden Vergleich zwischen den derzeit führenden Modellen auf dem Markt.
Abbildung 1: Der API-Checker verwendet eine statische Analysemethode und analysiert den generierten Code mit einem abstrakten Syntaxbaum (AST) .
Quelle: [1]
Die in Abbildung 2 dargestellten Ergebnisse verdeutlichen die Herausforderungen, mit denen Large-Language-Models (LLMs) bei der Codegenerierung konfrontiert sind. Obwohl die meisten Modelle in der Lage sind, in etwa 80 % der Fälle kompilierbaren Code zu erzeugen, was darauf hinweist, dass sie den grundlegenden Syntax-Anforderungen gerecht werden, zeigt sich ein bedenklicher Trend bei der korrekten Anwendung von APIs. Etwa die Hälfte des von den Modellen generierten kompilierbaren Codes weist eine Fehlverwendung der APIs auf, sogar, wenn ein korrektes Beispiel übergeben wird [1].
Abbildung 2: Ergebnis der API-Nutzung von LLMs
Quelle: [1]
Diese hohe Rate von API-Missbrauch ist alarmierend, da sie potenziell zu schwerwiegenden Problemen in den Softwareprodukten führen kann, wie Sicherheitslücken, Stabilitätsprobleme und Performanzeinbußen.
Mehr als 33 % des erzeugten Codes enthält Schwachstellen
Diese dramatischen Beobachtungen setzen sich auch dann fort, wenn der von LLMs generierte Code nach gängigen Programmierschwachstellen untersucht wird. Die Autoren des Artikels No Need to Lift a Finger Anymore? Assessing the Quality of Code Generation by ChatGPT untersuchen den von ChatGPT generierten Code auf 18 verbreitete Schwachstellen (Common Weakness Enumerations, CWEs) aus den Top 25 der MITRE-Liste.
Diese Schwachstellen sind potenzielle Sicherheitsrisiken, die es Angreifern erlauben könnten, die Systeme zu kompromittieren, Daten zu manipulieren oder unberechtigten Zugriff zu erlangen.
Für jede CWE werden drei verschiedene Code-Szenarien hergeleitet, anhand derer ChatGPT vollständige Code-Snippets in C und Python3 generieren soll. Diese Szenarien bestehen aus kleinen, unvollständigen Code-Schnipseln, die, wenn vervollständigt, spezifische und relevante CWEs enthalten könnten.
Die Forscher lassen ChatGPT für jedes Szenario 60 vollständige Code-Snippets generieren. Anschließend werden diese mithilfe von CodeQL analysiert.
Wie in Abbildung 3 dargestellt, war ChatGPT in der Lage 2.983 korrekte Codeschnipsel (99,07 %) zu generieren. Von diesen waren 994 angreifbar. Das entspricht 33,32 % [3].
Abbildung 3: Ergebnisse der CWE-Überprüfung
Quelle: [3]
Gestützt wird diese Erkenntnis durch eine Studie mit dem Namen Asleep at the Keyboard? Assessing the Security of GitHub Copilot’s Code Contributions, welche auf ähnliche Weise den generierten Code des von Github veröffentlichten KI-Programms Copilot analysiert. Die Studie kommt zu dem Ergebnis, dass etwa 40 % des generierten Codes Schwachstellen enthalten.
Anfang 2023 veröffentlicht Github eine Aktualisierung des Copilot-Systems und integriert ein Präventionsmechanismus, der mit Schwachstellen behafteten Code aus den Antworten von Copilot herausfiltern soll.
Eine neuere Studie mit dem Titel Is GitHub's Copilot as Bad as Humans at Introducing Vulnerabilities in Code aus Januar 2024 wiederholt die Untersuchung von Copilot in bezug auf Schwachstellen in ähnlicher Weise. Das Ergebnis ist: Copilot führt auch im Jahr 2024 in etwa 33 % der Szenarien eine Sicherheitsschwachstelle ein [4].
Interessant ist vor allem der zeitliche Unterschied: Zwischen den Studien liegen zwei Jahre, in denen zwar ein Schwachstellenfilter-System eingeführt wurde, es aber zu keiner nennenswerten Verbesserung der Codequalität in der Codegenerierung gekommen ist.
Stanford-Studie entlarvt Sicherheitsrisiken und Selbstüberschätzung unter Entwicklern
Die anfängliche geringe Qualität des von KI-Systemen generierten Codes stellt per se kein direktes Sicherheitsrisiko dar, da diese lediglich Vorschläge liefern, die einer menschlichen Überprüfung und Anpassung unterliegen. Es ist zu erwarten, dass in Praxissituationen ein Junior-Entwickler möglicherweise die Expertise eines Senior-Entwicklers hinzuzieht. Durch diese zusätzliche Überprüfungsebene wird eine entstandene Sicherheitsschwachstelle in der Regel identifiziert und korrigiert.
Eine im Jahr 2023 von der Stanford Universität durchgeführte Studie deutet leider auf das Gegenteil hin. In dieser Untersuchung wurde der Einfluss von KI-Systemen auf die Fähigkeit der Nutzer, korrekten und sicheren Code zu schreiben, anhand von Aufgaben in den Bereichen Verschlüsselung, digitale Signaturverfahren, Sandboxed-Directory, SQL und String-Manipulation analysiert. Besonders spannend: Es wurde die Selbsteinschätzung der Nutzer hinsichtlich der Korrektheit und Sicherheit ihrer Lösungsansätze evaluiert.
Die Studie zeigt, dass die Gruppe, die KI-Systeme zur Unterstützung einsetzte, im Durchschnitt nur in 46,4 % der Fälle korrekten Code erzeugen konnte, während es der Kontrollgruppe in 52,6 % der Fälle gelang. Dies deutet darauf hin, dass die Nutzung von KI-Systemen in dieser Studie keinen positiven Effekt auf die Wahrscheinlichkeit hatte, eine Aufgabe erfolgreich zu bewältigen. Allerdings sind diese Werte stark gemittelt, was es schwierig macht, einen direkten negativen Einfluss durch den Einsatz von KI zu konstatieren. Ein signifikanter Unterschied zeigt sich jedoch bei der Betrachtung der Code-Sicherheit: 48,6 % der von der Experimentgruppe eingereichten Lösungen wiesen Sicherheitsmängel auf, verglichen mit nur 25,6 % in der Kontrollgruppe. Die Autoren der Studie fassen ihre Erkenntnisse wie folgt zusammen:
Overall, we find that having access to the AI assistant (being in the experiment group) often results in more security vulnerabilities across multiple questions. The AI assistant often does not choose safe libraries, use libraries properly, understand the edge cases of interacting with external entities such as a file system or a database, and it does not correctly sanitize user input. [5]
Im Gegensatz zu den tatsächlichen Ergebnissen ist besonders auffällig, dass die Selbsteinschätzung der Teilnehmer, die KI-Systeme nutzen, stark von der Realität abweicht. Während sich die Kontrollgruppe ihrer Fähigkeiten realistisch bewusst ist, tendiert die Gruppe, die KI-Systeme einsetzt, zu einer erheblichen Überschätzung ihrer eigenen Kompetenzen. Bei jeder gestellten Aufgabe neigten die Teilnehmer der Versuchsgruppe, die unsichere Lösungen einreichten, signifikant häufiger dazu zu glauben, dass sie mithilfe der KI sicheren Code erzeugen können, im Vergleich zu denen, die tatsächlich sichere Lösungen lieferten. Zudem waren sie eher der Meinung, die Aufgaben sicher gelöst zu haben, als Teilnehmer der Kontrollgruppe, die ebenfalls unsichere Lösungen einreichten [5].
Fazit
Large Language Models (LLMs) haben zweifellos das Potenzial, den Prozess der Softwareentwicklung zu revolutionieren. Als jemand, der selbst solche Modelle in der Programmierarbeit einsetzt, kann ich die Effizienzsteigerung und Unterstützung, die sie bieten, persönlich bestätigen. Jedoch ist es unabdingbar, dass der generierte Code sorgfältig überprüft wird. Diese Notwendigkeit unterstreicht die Tatsache, dass, obwohl LLMs ein mächtiges Werkzeug sind, sie nicht fehlerfrei sind.
Besonders kritisch sehe ich den Einsatz von LLMs als Lerninstrument für Anfänger in der Programmierung. Die Gefahr besteht darin, dass Nutzer ungenaue oder ineffiziente Programmierpraktiken übernehmen, ohne dies zu hinterfragen. Wenn man sich zu sehr auf die Vorschläge der KI und damit den „Pilotensessel“ verlässt, um der KI das Steuer zu übergeben, begibt man sich auf dünnes Eis. Die Fähigkeit, Code kritisch zu evaluieren und zu verstehen, wird dadurch untergraben.
Ein weiteres bedeutsames Problem ist die Selbstüberschätzung, insbesondere bei jungen Entwicklern, die auf KI-Tools zur Codegenerierung zurückgreifen. Diese Selbstüberschätzung kann dazu führen, dass sie weniger geneigt sind, Rat und Feedback von erfahrenen Entwicklern einzuholen. Ein solches Verhalten könnte die traditionelle Praxis des Code-Reviews und den wertvollen Austausch zwischen jüngeren und erfahreneren Entwicklern untergraben.
In diesem Kontext gewinnt das Code-Review an Bedeutung. Es ist wichtiger denn je, als ein Instrument, um nicht nur die Qualität und Sicherheit des Codes zu gewährleisten, sondern auch als Lernmöglichkeit für Entwickler, um von ihren Kollegen zu lernen. Die Überprüfung durch Menschen bietet eine zusätzliche Sicherheitsebene, die sicherstellt, dass der Code nicht nur funktioniert, sondern auch Best Practices folgt und sicher ist.
Zusammenfassend lässt sich sagen, dass LLMs in der Programmierung eine wertvolle Hilfe darstellen können, vorausgesetzt, ihre Grenzen werden anerkannt und ihr Output wird kritisch hinterfragt. Der bewusste Umgang mit diesen Werkzeugen und die Aufrechterhaltung traditioneller Entwicklungspraktiken, wie das Peer-Review, sind entscheidend für die Sicherung der Codequalität und die Förderung eines gesunden Lernumfelds in der Softwareentwicklung.
Häufig ist die Durchführung einer externen Secure-Code-Review empfehlenswert, um eine zusätzliche Anwendungssicherheitsebene zu etablieren, sowie frühzeitig zu identifizieren, ob IT-Sicherheits-Schulungsbedarf der Entwickler besteht.
Literatur
[1] Li Zhong, Z. W. (2024) Can LLM Replace Stack Overflow? A Study on Robustness and Reliability of Large Language Model Code Generation. Available at: https://arxiv.org/html/2308.10335v5.
[2] BSI - Die Lage der IT-Sicherheit in Deutschland (no date). Available at: https://www.bsi.bund.de/DE/Service-Navi/Publikationen/Lagebericht/lagebericht_node.html.
[3] No Need to Lift a Finger Anymore? Assessing the Quality of Code Generation by ChatGPT (2023). Available at: https://arxiv.org/abs/2308.04838.
[4] Asare, O., Nagappan, M. and Asokan, N. (2023) ‘Is GitHub’s Copilot as bad as humans at introducing vulnerabilities in code?’, Empir. Softw. Eng. Springer Science and Business Media LLC, 28(6).
[5] Perry, N. et al. (2023) ‘Do Users Write More Insecure Code with AI Assistants?’, in Proceedings of the 2023 ACM SIGSAC Conference on Computer and Communications Security. New York, NY, USA: Association for Computing Machinery (CCS ’23), pp. 2785–2799. doi: 10.1145/3576915.3623157.