{"id":333497,"date":"2023-03-20T10:08:34","date_gmt":"2023-03-20T09:08:34","guid":{"rendered":"https:\/\/blog.jetbrains.com\/qodana\/2023\/03\/secure-your-php-code-with-taint-analysis-by-qodana\/"},"modified":"2023-09-04T16:18:45","modified_gmt":"2023-09-04T15:18:45","slug":"secure-your-php-code-with-taint-analysis-by-qodana","status":"publish","type":"qodana","link":"https:\/\/blog.jetbrains.com\/de\/qodana\/2023\/03\/secure-your-php-code-with-taint-analysis-by-qodana\/","title":{"rendered":"Sichern Sie Ihren PHP-Code durch Taint-Analysen in Qodana"},"content":{"rendered":"\n<p><em>Dieser Blogartikel wird Ihnen von Qodana pr\u00e4sentiert, der Codequalit\u00e4tsplattform von JetBrains. Die Plattform wurde entwickelt, um serverseitige statische Analysen in Ihrem bevorzugten CI-Tool zu erm\u00f6glichen. Durch die Verwendung derselben Codeinspektionen und Profile wie in PhpStorm und anderen JetBrains-IDEs sorgt Qodana f\u00fcr einheitliche Codequalit\u00e4tspr\u00fcfungen in Ihrer IDE und in Ihrer CI-Umgebung<\/em>.<\/p>\n\n\n\n<p>Es gen\u00fcgt, eine*n Benutzer*in zu kompromittieren, um eine Schwachstelle in Ihrem Projekt auszunutzen und in Ihr System einzudringen. Um Programme gegen b\u00f6swillige Eingaben (sogenannte \u201eTaints\u201c) durch externer Benutzer*innen zu sch\u00fctzen, f\u00fchren Entwicklungsteams im Zuge ihrer statischen Analysen auch Taint-Pr\u00fcfungen durch.<\/p>\n\n\n\n<p>In der ersten Version dieses Jahres hat das Qodana-Team im Rahmen des EAP-Programms eine Taint-Analyse f\u00fcr PHP bereitgestellt. Diese Funktion ist nur in Qodana for PHP 2023.1 (jetbrains\/qodana-php:2023.1-eap) verf\u00fcgbar. Qodana for PHP war der erste Linter, den wir ver\u00f6ffentlicht haben. Daher haben wir uns entschlossen, unsere neue Sicherheitsfunktionalit\u00e4t der PHP-Gemeinde zuerst zum Testen bereitzustellen. Sobald wir genug Feedback gesammelt haben, wollen wir weitere Sprachen hinzuf\u00fcgen.<\/p>\n\n\n\n<p>Lesen Sie weiter, um mehr dar\u00fcber zu erfahren, was Taint-Analysen sind und wie sie in Qodana funktionieren.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1200\" height=\"563\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/Blog_Featured_image_1280x600-5-1200x563.png\" alt=\"\" class=\"wp-image-333502\"\/><\/figure>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"jb-download-button\" title=\"QODANA KOSTENLOS AUSPROBIEREN\" href=\"https:\/\/www.jetbrains.com\/de-de\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>MIT QODANA LOSLEGEN<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Was ist eine Taint-Analyse?<\/h2>\n\n\n\n<p>Ein \u201eTaint\u201c ist jeder Wert, der ein Sicherheitsrisiko darstellen kann, wenn er von externen Benutzer*innen ge\u00e4ndert wird. Wenn durch einen Taint in Ihrem Code ungepr\u00fcfte externe Daten in Ihr Programm gelangen k\u00f6nnen, k\u00f6nnen Hacker dies zur Ausf\u00fchrung von Codefragmenten nutzen, um verschiedene Angriffe durchzuf\u00fchren, darunter SQL-Injection, arithmetische \u00dcberl\u00e4ufe, Cross-Site-Scripting, Path Traversal und mehr. Diese Schwachstellen werden in der Regel verwendet, um das System zu zerst\u00f6ren, Zugangsdaten und andere Informationen zu entwenden und das Systemverhalten zu \u00e4ndern.<\/p>\n\n\n\n<!--more-->\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1530\" height=\"590\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-34.png\" alt=\"\" class=\"wp-image-330043\"\/><figcaption>Beispiel f\u00fcr einen Taint. Daten aus dem GET-Parameter werden ungepr\u00fcft auf dem Bildschirm angezeigt. B\u00f6swillige Akteure k\u00f6nnen diese Sicherheitsl\u00fccke ausnutzen, um beispielsweise das Layout Ihres Programms zu manipulieren.&nbsp;&nbsp;<\/figcaption><\/figure>\n\n\n\n<p>Im Rahmen von Sicherheitsaudits, die die Angriffsfl\u00e4chen eines Programms untersuchen, f\u00fchren Entwicklungsteams Taint-Analysen als zus\u00e4tzliche Schutzma\u00dfnahme gegen b\u00f6swillige Eingaben durch.<\/p>\n\n\n\n<p><strong>Bei der Taint-Analyse wird der Weg einer nicht vertrauensw\u00fcrdigen Benutzereingabe durch die Gesamtheit einer Funktion oder Methode nachverfolgt. Dabei soll in erster Linie festgestellt werden, ob unvorhergesehene Eingaben die Programmausf\u00fchrung auf b\u00f6sartige Weise beeinflussen k\u00f6nnen.&nbsp;<\/strong><\/p>\n\n\n\n<p><strong>Taint-Quellen <\/strong>sind Stellen, an denen potenziell \u201ekontaminierte\u201c (\u201etainted\u201c) Daten in das Programm gelangen k\u00f6nnen. Wichtige Stellen in einem Programm, die f\u00fcr kontaminierte Eingaben anf\u00e4llig sind, werden als <strong>Taint-Senken<\/strong> bezeichnet. Die kontaminierten Daten k\u00f6nnen \u00fcber Funktionsaufrufe oder Zuweisungen zu den Senken gelangen.<\/p>\n\n\n\n<p>Bei der manuellen Taint-Analyse m\u00fcssen Sie alle Stellen identifizieren, an denen Daten von externen Benutzer*innen entgegengenommen werden, und die Wege jeder Eingabe durch das System verfolgen \u2013 die kontaminierten Daten werden oft an Dutzenden Stellen verwendet. Um die Ausbreitung von Taints zu verhindern, sollten Sie eine der beiden folgenden Methoden anwenden:<\/p>\n\n\n\n<ol><li><strong>Daten bereinigen<\/strong>, d.&nbsp;h. in eine sichere Form \u00fcberf\u00fchren. Im folgenden Beispiel entfernen wir Tags, um das Taint-Problem zu beheben.<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"249\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-24.png\" alt=\"\" class=\"wp-image-329878\"\/><\/figure>\n\n\n\n<ol start=\"2\"><li><strong>Daten validieren<\/strong>, d.&nbsp;h. \u00fcberpr\u00fcfen, ob die Dateneingaben einem bestimmten Muster entsprechen. Im folgenden Beispiel wird die Variable <code>$<\/code><code>email<\/code> einer Validierung unterzogen.<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"365\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-25.png\" alt=\"\" class=\"wp-image-329926\"\/><\/figure>\n\n\n\n<p>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\u00e4gt die Inspektion Alarm.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">So funktioniert die Taint-Analyse in Qodana<\/h2>\n\n\n\n<p>Die Taint-Analyse wird von Qodana for PHP ab Version 2023.1 EAP durchgef\u00fchrt. 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\u00f6ffnet werden, um das Problem an Ort und Stelle zu beheben.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Beispiel 1. SQL-Injektion<\/h3>\n\n\n\n<p>Sehen wir uns an, wie Qodana eine beispielhafte SQL-Injection erkennt:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"825\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-26.png\" alt=\"\" class=\"wp-image-329937\"\/><\/figure>\n\n\n\n<p>Hier weist uns Qodana auf die folgenden Taints in der Funktion system_admin() hin:<\/p>\n\n\n\n<p>Markierungen 1 und 2: Die benutzerseitigen Formulareingaben werden ohne Bereinigung oder Validierung aus dem globalen Array <code>$<\/code><code>_POST<\/code> in die Variable <code>$<\/code><code>edit<\/code> \u00fcbernommen. <strong>Das ist ein Taint.<\/strong><\/p>\n\n\n\n<p>Markierung 3: Die kontaminierte Variable <code>$<\/code><code>edit<\/code> wird als Argument an die Funktion <code>system_save_settings<\/code> \u00fcbergeben, ohne dass eine ordnungsgem\u00e4\u00dfe Bereinigung erfolgt.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"527\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-27.png\" alt=\"\" class=\"wp-image-329949\"\/><\/figure>\n\n\n\n<p>Markierung 4: Die aus der Variablen <code>$<\/code><code>edit<\/code> stammenden Daten befinden sich jetzt im Parameter <code>$<\/code><code>edit<\/code>.<\/p>\n\n\n\n<p>Markierung 5: Die Variable <code>$<\/code><code>edit<\/code> wird an die <code>foreach<\/code>-Schleife mit dem Schl\u00fcssel <code>$<\/code><code>filename<\/code> und dem Wert <code>$<\/code><code>status<\/code> \u00fcbergeben. Beide Variablen enthalten die kontaminierten Daten aus der Variablen <code>$<\/code><code>edit<\/code>, die mit der Zeichenfolge verkettet wurde. Der Schl\u00fcssel <code>$<\/code><code>filename<\/code> wird mit einer kontaminierten SQL-Zeichenfolge verkettet und so werden die kontaminierten Daten in ein Argument \u00fcbernommen, das an <code>db_query<\/code> \u00fcbergeben wird.<\/p>\n\n\n\n<p>Markierung 6: Der Schl\u00fcssel <code>$<\/code><code>filename<\/code> enth\u00e4lt die kontaminierten Daten aus der Variablen <code>$<\/code><code>edit<\/code>, die mit der Zeichenkette verkettet werden.<\/p>\n\n\n\n<p>Markierung 7: Der Schl\u00fcssel <code>$<\/code><code>filename<\/code> wird mit einer kontaminierten SQL-Zeichenfolge verkettet.<\/p>\n\n\n\n<p>Markierung 8: Die kontaminierte SQL-Zeichenfolge tr\u00e4gt die kontaminierten Daten in ein Argument weiter, das an <code>db_query<\/code> \u00fcbergeben wird.<\/p>\n\n\n\n<p>Wenden wir uns nun der Funktion db_query zu:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"571\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-28.png\" alt=\"\" class=\"wp-image-329960\"\/><\/figure>\n\n\n\n<p>Markierung 9: Die kontaminierte Zeichenkette befindet sich im Parameter <code>$<\/code><code>query<\/code>.<\/p>\n\n\n\n<p>Markierung 10: Dieser Parameter wird als Argument an die Funktion _db_query \u00fcbergeben.<\/p>\n\n\n\n<p>Sehen wir uns nun die Funktion <code>_db_query<\/code> an:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"680\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-33.png\" alt=\"\" class=\"wp-image-330032\"\/><\/figure>\n\n\n\n<p>Markierung 11: Der erste Parameter <code>$<\/code><code>query<\/code> der Funktion <code>_db_query<\/code> enth\u00e4lt kontaminierte Daten.<\/p>\n\n\n\n<p>Markierung 12: Die Daten aus dem Parameter werden an die Funktion <code>mysql_query<\/code> \u00fcbergeben, die in diesem Fall eine Senke ist.<\/p>\n\n\n\n<p>Der obige Datenfluss veranschaulicht, wie Daten aus <code>$<\/code><code>_POST[\"edit\"]<\/code> ohne jegliche Bereinigung oder Validierung an <code>mysql_query(<!--0-->&lt;0&gt;$<!--0-->&lt;0&gt;query)<!--0--> \u00fcbergeben werden. Dadurch k\u00f6nnen Angreifer die SQL-Abfrage manipulieren, die mit einem Schl\u00fcssel aus <code>$<\/code><code>_POST[\"edit\"]<\/code> verkettet wird, und so eine <strong>SQL-Injection<\/strong> ausl\u00f6sen.&nbsp;<\/code><\/p>\n\n\n\n<p><code>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\u00f6nnen.&nbsp;<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/resources.jetbrains.com\/storage\/products\/blog\/wp-content\/uploads\/Qodana\/taint-open.gif\" alt=\"\"\/><figcaption>\u00d6ffnen des Problems in PhpStorm.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Beispiel 2. XSS-Problem<\/h3>\n\n\n\n<p>In der Qodana-Bedienoberfl\u00e4che k\u00f6nnen Sie den gesamten Taint-Datenfluss in einem Diagramm nachverfolgen. Im Folgenden sehen Sie die Visualisierung einer XSS-L\u00fccke mit 2 Quellen, die bei Markierung 5 zusammengef\u00fchrt werden.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1310\" height=\"750\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-29.png\" alt=\"\" class=\"wp-image-329971\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1170\" height=\"714\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-30.png\" alt=\"\" class=\"wp-image-329982\"\/><\/figure>\n\n\n\n<p><strong>Quelle 1<\/strong><\/p>\n\n\n\n<p><code><\/code><code><\/code><code><\/code><code><\/code><code>Markierungen 1 und 2: Daten aus der Datei <\/code>searchUpdate.pos werden eingelesen und kontaminierte Daten werden der Variablen <code>$<\/code><code>start<\/code> zugewiesen.<\/p>\n\n\n\n<p><strong>Quelle 2<\/strong><\/p>\n\n\n\n<p>Markierungen 3 und 4: Daten aus Dateien, deren Pfad in <code>$<\/code><code>posFile<\/code> gespeichert sind, werden eingelesen und kontaminierte Daten werden der Variablen <code>$<\/code><code>start<\/code> zugewiesen.<\/p>\n\n\n\n<p>Markierung 5: Zusammengef\u00fchrte kontaminierte Daten aus allen Bedingungszweigen, die in der Variablen <code>$<\/code><code>start<\/code> gespeichert sind, werden als Argument an die Methode <code>doUpdateSearchIndex<\/code> \u00fcbergeben.<\/p>\n\n\n\n<p>Werfen wir nun einen Blick auf die Methode <code>doUpdateSearchIndex()<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1170\" height=\"522\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-31.png\" alt=\"\" class=\"wp-image-329994\"\/><\/figure>\n\n\n\n<p>Markierungen 6 und 8: In diesem Datenfluss-Abschnitt enth\u00e4lt der Parameter <code>$<\/code><code>start<\/code> kontaminierte Daten, die in einer verketteten Zeichenfolge als Argument an die Methode <code>output<\/code> \u00fcbergeben werden.<\/p>\n\n\n\n<p>Sehen wir uns nun die Methode <code>output<\/code> an:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"1170\" height=\"764\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/03\/image-32.png\" alt=\"\" class=\"wp-image-330005\"\/><\/figure>\n\n\n\n<p>Markierung 9: Die in der \u00fcbergebenen Zeichenfolge enthaltenen kontaminierten Daten befinden sich im Parameter <code>$<\/code><code>out<\/code>.<\/p>\n\n\n\n<p>Markierung 10: Die Daten aus dem Parameter <code>$<\/code><code>out<\/code> werden ohne jegliche Bereinigung an die Funktion <code>print<\/code> \u00fcbergeben. Diese Funktion ist eine Senke und stellt eine ausnutzbare XSS-Schwachstelle dar.<\/p>\n\n\n\n<p>Um die Schwachstelle auszunutzen, k\u00f6nnten Angreifer beispielsweise an den Markierungen 1 und 2 ein Befehlszeilen-Skript anstelle der erwarteten Dateien hochladen, und sie k\u00f6nnen aufgrund der fehlenden Bereinigung in der print-Funktion beliebige Informationen auf der Webseite anzeigen.<\/p>\n\n\n\n<p>Qodana weist Sie auf diese Sicherheitsl\u00fccke hin und ordnet ihr eine hohe Priorit\u00e4t zu, damit Sie das Problem so schnell wie m\u00f6glich beheben und Angriffe verhindern k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Taint-Analysen k\u00f6nnen Ihnen helfen, ausnutzbare Anf\u00e4lligkeiten 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 <a title=\"https:\/\/www.jetbrains.com\/help\/qodana\/getting-started.html\" href=\"https:\/\/www.jetbrains.com\/help\/qodana\/2023.1\/taint-analysis.html\" target=\"_blank\" rel=\"noreferrer noopener\">Qodana-Dokumentation<\/a>.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"jb-download-button\" title=\"MIT QODANA LOSLEGEN\" href=\"https:\/\/www.jetbrains.com\/de-de\/qodana\" target=\"_blank\" rel=\"noopener noreferrer\"><i class=\"download-icon\"><\/i>MIT QODANA LOSLEGEN<\/a><\/p>\n\n\n\n<p>Viel Freude beim Entwickeln \u2013 und halten Sie Ihren Code fit!<\/p>\n\n\n\n<p><strong>Autorin des Original-Blogposts:<\/strong><\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":811,"featured_media":333502,"comment_status":"closed","ping_status":"closed","template":"","categories":[89,6366],"tags":[],"cross-post-tag":[6637],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/qodana\/333497"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/qodana"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/types\/qodana"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/users\/811"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/comments?post=333497"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/qodana\/333497\/revisions"}],"predecessor-version":[{"id":333532,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/qodana\/333497\/revisions\/333532"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media\/333502"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/media?parent=333497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/categories?post=333497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/tags?post=333497"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/de\/wp-json\/wp\/v2\/cross-post-tag?post=333497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}