Qodana
The code quality platform for teams
Sichern Sie Ihren PHP-Code durch Taint-Analysen in Qodana
Dieser Blogartikel wird Ihnen von Qodana präsentiert, der Codequalitätsplattform von JetBrains. Die Plattform wurde entwickelt, um serverseitige statische Analysen in Ihrem bevorzugten CI-Tool zu ermöglichen. Durch die Verwendung derselben Codeinspektionen und Profile wie in PhpStorm und anderen JetBrains-IDEs sorgt Qodana für einheitliche Codequalitätsprüfungen in Ihrer IDE und in Ihrer CI-Umgebung.
Es genügt, eine*n Benutzer*in zu kompromittieren, um eine Schwachstelle in Ihrem Projekt auszunutzen und in Ihr System einzudringen. Um Programme gegen böswillige Eingaben (sogenannte „Taints“) durch externer Benutzer*innen zu schützen, führen Entwicklungsteams im Zuge ihrer statischen Analysen auch Taint-Prüfungen durch.
In der ersten Version dieses Jahres hat das Qodana-Team im Rahmen des EAP-Programms eine Taint-Analyse für PHP bereitgestellt. Diese Funktion ist nur in Qodana for PHP 2023.1 (jetbrains/qodana-php:2023.1-eap) verfügbar. Qodana for PHP war der erste Linter, den wir veröffentlicht haben. Daher haben wir uns entschlossen, unsere neue Sicherheitsfunktionalität der PHP-Gemeinde zuerst zum Testen bereitzustellen. Sobald wir genug Feedback gesammelt haben, wollen wir weitere Sprachen hinzufügen.
Lesen Sie weiter, um mehr darüber zu erfahren, was Taint-Analysen sind und wie sie in Qodana funktionieren.
Was ist eine Taint-Analyse?
Ein „Taint“ ist jeder Wert, der ein Sicherheitsrisiko darstellen kann, wenn er von externen Benutzer*innen geändert wird. Wenn durch einen Taint in Ihrem Code ungeprüfte externe Daten in Ihr Programm gelangen können, können Hacker dies zur Ausführung von Codefragmenten nutzen, um verschiedene Angriffe durchzuführen, darunter SQL-Injection, arithmetische Überläufe, Cross-Site-Scripting, Path Traversal und mehr. Diese Schwachstellen werden in der Regel verwendet, um das System zu zerstören, Zugangsdaten und andere Informationen zu entwenden und das Systemverhalten zu ändern.
Im Rahmen von Sicherheitsaudits, die die Angriffsflächen eines Programms untersuchen, führen Entwicklungsteams Taint-Analysen als zusätzliche Schutzmaßnahme gegen böswillige Eingaben durch.
Bei der Taint-Analyse wird der Weg einer nicht vertrauenswürdigen Benutzereingabe durch die Gesamtheit einer Funktion oder Methode nachverfolgt. Dabei soll in erster Linie festgestellt werden, ob unvorhergesehene Eingaben die Programmausführung auf bösartige Weise beeinflussen können.
Taint-Quellen sind Stellen, an denen potenziell „kontaminierte“ („tainted“) Daten in das Programm gelangen können. Wichtige Stellen in einem Programm, die für kontaminierte Eingaben anfällig sind, werden als Taint-Senken bezeichnet. Die kontaminierten Daten können über Funktionsaufrufe oder Zuweisungen zu den Senken gelangen.
Bei der manuellen Taint-Analyse müssen Sie alle Stellen identifizieren, an denen Daten von externen Benutzer*innen entgegengenommen werden, und die Wege jeder Eingabe durch das System verfolgen – die kontaminierten Daten werden oft an Dutzenden Stellen verwendet. Um die Ausbreitung von Taints zu verhindern, sollten Sie eine der beiden folgenden Methoden anwenden:
- Daten bereinigen, d. h. in eine sichere Form überführen. Im folgenden Beispiel entfernen wir Tags, um das Taint-Problem zu beheben.
- Daten validieren, d. h. überprüfen, ob die Dateneingaben einem bestimmten Muster entsprechen. Im folgenden Beispiel wird die Variable
$
email
einer Validierung unterzogen.
Die Taint-Analyse verfolgt also Benutzereingaben von ihrer Quelle bis zu den Senken in Ihrem Programm. Wenn Sie diese Daten verwenden, ohne sie zu bereinigen oder zu validieren, schlägt die Inspektion Alarm.
So funktioniert die Taint-Analyse in Qodana
Die Taint-Analyse wird von Qodana for PHP ab Version 2023.1 EAP durchgeführt. Dabei scannt eine Inspektion den Code und hebt den Taint und die potenzielle Schwachstelle hervor. Ein Datenflussdiagramm visualisiert den Taint-Datenfluss, und die problematische Stelle kann in PhpStorm geöffnet werden, um das Problem an Ort und Stelle zu beheben.
Beispiel 1. SQL-Injektion
Sehen wir uns an, wie Qodana eine beispielhafte SQL-Injection erkennt:
Hier weist uns Qodana auf die folgenden Taints in der Funktion system_admin() hin:
Markierungen 1 und 2: Die benutzerseitigen Formulareingaben werden ohne Bereinigung oder Validierung aus dem globalen Array $
_POST
in die Variable $
edit
übernommen. Das ist ein Taint.
Markierung 3: Die kontaminierte Variable $
edit
wird als Argument an die Funktion system_save_settings
übergeben, ohne dass eine ordnungsgemäße Bereinigung erfolgt.
Markierung 4: Die aus der Variablen $
edit
stammenden Daten befinden sich jetzt im Parameter $
edit
.
Markierung 5: Die Variable $
edit
wird an die foreach
-Schleife mit dem Schlüssel $
filename
und dem Wert $
status
übergeben. Beide Variablen enthalten die kontaminierten Daten aus der Variablen $
edit
, die mit der Zeichenfolge verkettet wurde. Der Schlüssel $
filename
wird mit einer kontaminierten SQL-Zeichenfolge verkettet und so werden die kontaminierten Daten in ein Argument übernommen, das an db_query
übergeben wird.
Markierung 6: Der Schlüssel $
filename
enthält die kontaminierten Daten aus der Variablen $
edit
, die mit der Zeichenkette verkettet werden.
Markierung 7: Der Schlüssel $
filename
wird mit einer kontaminierten SQL-Zeichenfolge verkettet.
Markierung 8: Die kontaminierte SQL-Zeichenfolge trägt die kontaminierten Daten in ein Argument weiter, das an db_query
übergeben wird.
Wenden wir uns nun der Funktion db_query zu:
Markierung 9: Die kontaminierte Zeichenkette befindet sich im Parameter $
query
.
Markierung 10: Dieser Parameter wird als Argument an die Funktion _db_query übergeben.
Sehen wir uns nun die Funktion _db_query
an:
Markierung 11: Der erste Parameter $
query
der Funktion _db_query
enthält kontaminierte Daten.
Markierung 12: Die Daten aus dem Parameter werden an die Funktion mysql_query
übergeben, die in diesem Fall eine Senke ist.
Der obige Datenfluss veranschaulicht, wie Daten aus $
_POST["edit"]
ohne jegliche Bereinigung oder Validierung an mysql_query(<0>$<0>query) übergeben werden. Dadurch können Angreifer die SQL-Abfrage manipulieren, die mit einem Schlüssel aus
$
_POST["edit"]
verkettet wird, und so eine SQL-Injection auslösen.
Qodana erkennt diese Risiken in Ihrem Codebestand und identifiziert allen Knoten, an denen kontaminierte Daten verwendet werden, sodass Sie alle kontaminierten Daten rechtzeitig bereinigen können.
Beispiel 2. XSS-Problem
In der Qodana-Bedienoberfläche können Sie den gesamten Taint-Datenfluss in einem Diagramm nachverfolgen. Im Folgenden sehen Sie die Visualisierung einer XSS-Lücke mit 2 Quellen, die bei Markierung 5 zusammengeführt werden.
Quelle 1
Markierungen 1 und 2: Daten aus der Datei
searchUpdate.pos werden eingelesen und kontaminierte Daten werden der Variablen $
start
zugewiesen.
Quelle 2
Markierungen 3 und 4: Daten aus Dateien, deren Pfad in $
posFile
gespeichert sind, werden eingelesen und kontaminierte Daten werden der Variablen $
start
zugewiesen.
Markierung 5: Zusammengeführte kontaminierte Daten aus allen Bedingungszweigen, die in der Variablen $
start
gespeichert sind, werden als Argument an die Methode doUpdateSearchIndex
übergeben.
Werfen wir nun einen Blick auf die Methode doUpdateSearchIndex()
:
Markierungen 6 und 8: In diesem Datenfluss-Abschnitt enthält der Parameter $
start
kontaminierte Daten, die in einer verketteten Zeichenfolge als Argument an die Methode output
übergeben werden.
Sehen wir uns nun die Methode output
an:
Markierung 9: Die in der übergebenen Zeichenfolge enthaltenen kontaminierten Daten befinden sich im Parameter $
out
.
Markierung 10: Die Daten aus dem Parameter $
out
werden ohne jegliche Bereinigung an die Funktion print
übergeben. Diese Funktion ist eine Senke und stellt eine ausnutzbare XSS-Schwachstelle dar.
Um die Schwachstelle auszunutzen, könnten Angreifer beispielsweise an den Markierungen 1 und 2 ein Befehlszeilen-Skript anstelle der erwarteten Dateien hochladen, und sie können aufgrund der fehlenden Bereinigung in der print-Funktion beliebige Informationen auf der Webseite anzeigen.
Qodana weist Sie auf diese Sicherheitslücke hin und ordnet ihr eine hohe Priorität zu, damit Sie das Problem so schnell wie möglich beheben und Angriffe verhindern können.
Fazit
Taint-Analysen können Ihnen helfen, ausnutzbare Anfälligkeiten zu beseitigen. Sie sind daher eine effektive Methode zur Minimierung der mit Ihrer Software verbundenen Risiken. Weitere Informationen zur Taint-Analyse und Qodana finden Sie in der Qodana-Dokumentation.
Viel Freude beim Entwickeln – und halten Sie Ihren Code fit!
Autorin des Original-Blogposts: