PHP absichern

So wird PHP sicherer

25.04.2015 von Stephan Lamprecht
Die Script-Sprache PHP ist eine wesentliche Voraussetzung für dynamische Webinhalte. PHP gilt allerdings als nicht besonders sicher. Doch es gibt einige Pflichtmaßnahmen, die die Sicherheit von PHP-Scripts deutlich erhöhen.

Programme wie Wordpress oder Typo 3 basieren in weiten Teilen auf PHP. Seit der ersten Veröffentlichung im Jahr 1995 wurde der Hypertext Preprocessor zu einem der wichtigsten Werkzeuge bei der Entwicklung von dynamischen Webseiten. Mit PHP-Programmen ist viel möglich, doch sorgen besonders Funktionen immer wieder für Ärger, mit denen sich Inhalte aus Datenbanken auslesen und bearbeiten lassen. Angreifer nutzen dabei oft gerade entdeckte Sicherheitslücken. Häufig öffnet aber sträflicher Leichtsinn des Administrators das Tor für erfolgreiche Angriffe.

Sichern Sie die PHP-Installation ab

Ob Sie einen lokalen Webserver betreiben, der nur für wenige Stunden öffentlich zugänglich ist, oder mit einem dedizierten Server bei einem Provider arbeiten: Lücken in PHP werden von Bots und automatisierten Scripts immer auch als Sprungbrett genutzt, um tiefer in andere Systeme einzudringen. Eine sichere PHP-Umgebung beginnt mit der Konfiguration der Bibliotheken. Wenn Sie sich die aktuelle PHP-Konfiguration ansehen wollen, legen Sie mit einem Editor Ihrer Wahl eine Datei mit beliebigem Namen und der Endung „.php“ an. In die Datei schreiben Sie:

<?
phpinfo();
?>

Die Datei laden Sie dann etwa in das Verzeichnis „/var/www/“ beziehungsweise „/var/www/html/“ hoch. Rufen Sie dann mit einem Browser die Datei von Ihrem Server ab. PHP liefert nun alle Einstellungen übersichtlich aus und zeigt auch Hinweise auf installierte Module.

PHP-Infodatei auf dem Server: Drei Zeilen PHP-Code genügen, um sich die aktuelle Konfiguration von PHP auf dem Server anzusehen.

Als Einstellungszentrale für PHP dient die Datei „php.ini“, die auf Linux-Systemen meist im Verzeichnis „/etc/“ liegt. Unter Ubuntu etwa finden Sie die Datei unter „etc/php5/apache2“, sofern mit dem Apache-Server gearbeitet wird. In dieser „php.ini“ suchen Sie nach dem Eintrag „register_globals“ und ändern den Wert zu „register_globals = Off“. Ist die Zeile bisher nicht vorhanden, legen Sie sie neu an. Damit vermeiden Sie, dass ein Angreifer auf die Parameter aus einer URL direkt zugreifen kann, um sie für eigene Zwecke zu nutzen. Ahnt ein Angreifer das Vorhandensein eines Scripts oder ist dessen Existenz bekannt (etwa im Fall von Standardsoftware), kann er ihm eigene Variablen übergeben, ohne dass diese erst definiert werden müssten. Schalten Sie außerdem die Anzeige von Fehlermeldungen aus. Denn die Fehlermeldungen im Browser liefern Hackern und Angreifern wichtige Informationen, die sich eventuell kreativ ausnutzen lassen. Auf einem Produktivsystem, das im Web erreichbar ist, sollte daher in der „php.ini“ die Anweisung „display_errors=“ auf „Off“ gesetzt sein.

HTML-Ausgabe von phpinfo(): Der Server liefert auf einer übersichtlichen Seite alle Einstellungen und Komponenten der PHP-Installation aus.

Weisen Sie neugierige Blicke zurück

Viele Sicherheitsprobleme erwachsen aus einer unzureichend abgesicherten Installation des Webservers oder aus unverhältnismäßigem Vertrauen in die Nutzer. Bei der Entwicklung eines Scripts sollte darauf geachtet werden, dass alle externen Informationen und Elemente außerhalb der Hierarchie des Ordners für Webdokumente abgelegt werden. Damit der Server Seiten und Scripts ausliefern kann, müssen diese im Ordner „/var/www“ liegen. Das gilt aber keineswegs für Bildreferenzen oder andere Dateien. Greifen Sie mit absoluten Pfadangaben darauf zu.

Verbieten Sie zusätzlich dem Nutzer das Blättern in Verzeichnissen. Machen Sie die Probe aufs Exempel: Wo Sie ein Dokument mit der Adresse „www.name.tld/verzeichnis/name.htm“ im Web abrufen können, lassen Sie einfach versuchsweise den Namen der Datei weg. Sie werden überrascht sein, auf wie vielen Servern Sie anschließend die gesamte Verzeichnisstruktur sehen können. Um solches Blättern zu verbieten, schützen Sie die Verzeichnisse des Servers durch das Anlegen der Datei „.htaccess“. In dieser verwenden Sie diese Anweisung:

Options –Indexes

Das verbietet das Anzeigen von Verzeichnisinhalten.

Beugen Sie SQL-Injektionen vor

SQL-Injektionen schleusen bei Abfragen zusätzliche Werte ein, die an die Datenbank übergeben werden. Ist das Script nicht geschützt, kann ein Angreifer schlimmstenfalls Daten auslesen. Verringern können Sie dieses Risiko durch die Verwendung des PHP-Moduls Mysqli. Um etwa aus einer Tabelle „mitglieder“ einen Benutzernamen auszulesen, sieht der Aufruf so aus:

$username = mysqli_real_escape_string( $GET['username'] );
mysql_query("SELECT * FROM mitglieder WHERE username = ' ".$username." ' ");

Mysqli prüft die Gültigkeit eingegebener Parameter und verhindert SQL-Injektionen.

Mysqli nutzt Prepared Statements: Dabei erhält die Abfrage Platzhalter an den Stellen, wo Variablen gelesen oder übergeben werden sollen. Dies lässt sich auch manuell durch entsprechenden Code erzielen und sieht im Prinzip so aus:

$stmt = $db->stmt_init();
$stmt = prepare( "SELECT * FROM mitglieder WHERE id = ?" );
// Statement an Parameter binden. i steht fuer Integer
$stmt->bind_param( "i", $id );
// Statement ausfuehren
$stmt->execute();

Dieses Beispiel fragt das Feld „id“ in der Datenbank ab. Genutzt wird dann innerhalb des Statements die Variable „$id“.

Misstrauen Sie Nutzereingaben

Robots und Angreifer werden stets versuchen, in URLs, Funktionsaufrufen oder Formularfeldern Code einzuschleusen, um herauszufinden, wie die PHP-Anwendung reagiert. Die wichtigste Regel ist das Misstrauen gegenüber Benutzereingaben. Akzeptieren Sie nur Eingaben, die Sie geprüft haben. Das macht mehr Arbeit bei der Entwicklung, erhöht aber die Sicherheit.

Kontrolle der Benutzerrechte: Neben der wichtigen Absicherung von PHP sollten Sie nicht vergessen, die Rechte im Ordner mit den HTML-Dokumenten zu kontrollieren.

Ein Beispiel: Ein Formular, in das der Nutzer sein Geburtsdatum eintragen soll, erlaubt Tag und Monat jeweils zweistellig und eine vierstellige Jahresangabe. Alles andere ist nicht erlaubt. Diese Angaben müssen nun geprüft werden. Dazu bedienen Sie sich regulärer Ausdrücke. Der Umgang damit fällt Einsteigern nicht ganz leicht, weil nicht nur die Syntax erlernt werden will, sondern zuerst die passende Bedingung gefunden werden muss, die dann dargestellt werden soll. Überprüfen Sie also bei allen Eingaben des Nutzers in Form von „POST“ oder „GET“ die erlaubten Zeichen und die Länge der Eingabe. Eine Validierung für das genannte Beispiel sieht im Prinzip so aus:

if (! preg_match("/^[0-9]{1,2} $/", $_GET['tag']))
{
// Fehlermeldung
}
if (! preg_match("/^[0-9]{1,2} $/", $_GET['monat']))
{
// Fehlermeldung
}
if (! preg_match("/^[0-9]{4} $/", $_GET['jahr']))
{
// Fehlermeldung
}

Wenn Sie diese Maßnahmen bei der Entwicklung eigener Scripts und der Konfiguration des Servers berücksichtigen, haben Sie prominente Einfallstore von Hackern und Datendieben erfolgreich geschlossen.

(PC-Welt/ad)