O'Reilly logo

PHP-Sicherheit: PHP/MySQL-Webanwendungen sicher programmieren by Stefan Esser, Christopher Kunz

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

753.5 register_globals
Sie sehen, dass Blacklist-Überprüfungen von einer meist
unzutreffenden Annahme ausgehen – nämlich der, dass alle »bösen«
Zeichen oder Zeichensequenzen dem Entwickler bekannt sind. White-
listing ist in den meisten Fällen deutlich effektiver und zukunftssiche-
rer, da es im Zweifelsfall nur auf weniger harmlose Zeichen beschränkt
ist, statt grundsätzlich allen Zeichen, die nicht explizit benannt sind,
eine weiße Weste zu bescheinigen.
Beide Arten sind nicht wartungsfrei, aber Blacklisting erfordert
deutlich mehr Wartungsaufwand durch permanentes Finden und
Beseitigen von Sicherheitslücken.
3.4.6 Clientseitige Validierung
Eine clientseitige Validierung sollte nie als alleinige Lösung zur Variab-
lenvalidierung dienen. Diese Art der Prüfung basiert meistens auf Java-
Script; dies kann in jedem Browser deaktiviert werden. Da JavaScript
eine clientseitige Skriptsprache ist, gelten hierfür ebenfalls alle
Manipulationsmöglichkeiten, die für Parameter gelten. Der Java-
Script-Code kann mittels eines Proxys oder eines entsprechenden
Browser-Plugins (siehe Abschnitt 3.2.1) verändert werden. Somit ist
die clientseitige Validierung nie eine alleinige Prüfungsmöglichkeit für
Variablen oder Formularinhalte. Sie kann lediglich als Zusatz gesehen
werden.
Die endgültige Validierung sollte immer am Server geschehen.
Dazu können die in diesem Kapitel erklärten Mechanismen verwendet
werden.
3.5 register_globals
Manche Konfigurationsoptionen von PHP werden als gefährlich ange-
sehen, was aber nicht der Wahrheit entspricht. Gefährlich werden
diese Optionen nur im Zusammenhang mit Schwachstellen, die sich in
Applikationen befinden.
PHP in seiner Grundkonfiguration bietet durchaus Anlass für
sicherheitstechnische Diskussionen, was Konfigurationseinstellungen
anbelangt. Die Datei
php.ini-dist, die jedem PHP-Quellarchiv bei-
liegt, wird von den meisten Anbietern von Linux-Distributionen eben-
falls als Basis für ihre PHP-Version verwendet und dient somit auch als
Grundlage für die folgenden Betrachtungen.
63/8>=/3>31/&+63.3/<?81/<2J2>.3/%=+,363>C3=>+,/<5/38/#-2?>D7J163-2
5/3>1/1/8 +<+7/>/<7+83:?6+>398
3 Parametermanipulation76
Ursprünglich verwendeten PHP-Programmierer den »register glo-
bals«-Mechanismus, um auf Variablen zuzugreifen, die aus dem User-
Bereich kamen. In dieser Einstellung ist jede Variable, die an ein PHP-
Skript übermittelt wird, im globalen Namensraum mit demselben
Namen wie der Parameter verfügbar. Ein Beispiel:
http://www.beispiel.de/index.php?name=inhalt
Diese URL generiert für die Datei index.php eine Variable name mit dem
Inhalt
inhalt im globalen Namensraum für Variablen. Dieser Automa-
tismus führte und führt immer noch zu verschiedenen Schwachstellen
und Problemen.
Ein Problem hierbei ist die Reihenfolge, wie die Parameter in
einem Skript registriert werden. Hierbei kann es zu Namenskonflikten
kommen, wenn ein GET-Parameter den gleichen Namen hat wie ein
POST-Parameter. Der PHP-Interpreter überschreibt dann eine der bei-
den Variablen, je nachdem, was die Einstellung
gpc_order bzw. die neu-
ere Direktive
variables_order enthält. Beide Einstellungen geben die
Reihenfolge der Variablenregistrierung des PHP-Interpreters an. In der
Defaulteinstellung hat
variables_order den Wert EGPCS (System-Envi-
ronment, GET, POST, Cookie, Session), wobei Session-Variablen hier
die oberste Priorität haben – sie werden zuletzt registriert, überschrei-
ben also sämtliche gleichnamigen Variablen aus GET, POST oder
Cookies. Um die durch diese Überschreibung auftretenden Probleme
zu lindern, wurden für jeden Bereich eigene Variablen mit dem
Namensschema
HTTP_*_VARS eingeführt. So wurden die Namensräume
in
HTTP_GET_VARS, HTTP_POST_VARS und HTTP_COOKIE_VARS aufgeteilt. Leider
waren diese Variablen nicht superglobal verfügbar, also aus Funktio-
nen heraus nicht ohne Weiteres zugänglich. Der Entwickler musste die
Werte aus dem Array
$GLOBALS auslesen. Auch von dieser Methode
raten Experten mittlerweile ab, sie wird aber in manchen Skripten
immer noch verwendet.
Der schlechte Ruf dieser Konfigurationsvariablen als Verursacher
von Sicherheitsproblemen basiert ausschließlich darauf, dass PHP-Ent-
wickler häufig vergessen, Variablen vor der ersten Benutzung korrekt
zu initialisieren. Denn durch diesen Schalter ist es für einen Angreifer
möglich, uninitialisierte Variablen, die ursprünglich beispielsweise aus
einem Formular übertragen werden sollten, über die URL zu initialisie-
ren.
Uninitialisierte Variablen
Viele Programmierer prüfen, ob sich in Variablen Inhalte befinden
oder nicht. Falls die Variable leer ist, zum Beispiel beim ersten Aufruf,
macht die Applikation etwas anderes, als wenn die Variable mit Inhalt
gefüllt ist. In dem folgenden Beispiel soll durch einen Link ein Datei-
name
$file_to_load an ein Skript übermittelt werden.
773.5 register_globals
<a href="/files/file1.php">Link zur Datei 1</a>
[...]
<?php
$securefiles = array('file1.php','file2.php','file3.php');
if ( in_array($_GET['page'],$securefiles))
$file_to_load = $_GET['page'];
[...]
if ( isset($file_to_load)) {
include ($file_to_load);
} else {
include ('index.php');
}
?>
Sicherheitslücke durch
fehlende Initialisierung
Ist register_globals eingeschaltet und die Applikation würde mit
skript.php?file_to_load=/etc/passwd aufgerufen werden, lädt der PHP-
Interpreter diese Datei auch. Bei ausgeschaltetem
register_globals
könnte die Variable $file_to_load nicht per URL überschrieben wer-
den. Durch eine Initialisierung der Variablen
$file_to_load vor der
Zuweisung
$file_to_load = $_GET['page']; wäre dieser include()-Befehl
auch bei eingeschaltetem
register_globals abgesichert.
<?php
$file_to_load='';
$securefiles = array('file1.php','file2.php','file3.php');
if ( in_array($_GET['page'],$securefiles))
$file_to_load = $_GET['page'];
else
header('Location:index.php');
[...]
?>
Leider wird es wegen der Rückwärtskompatibilität oft nötig, die
Konfigurationsoption
register_globals einzuschalten. Der Grund
dafür können ältere Applikationen sein, die auf
register_globals ange-
wiesen sind. Falls dies bei Ihrem Server der Fall ist und Sie einen
zusätzlichen Schutz gegen Angriffe durch Überschreiben von Variablen
möchten, empfehlen wir folgenden Programmcode. Egal, ob auf dem
produktiven System nun
register_globals ein- oder ausgeschaltet ist,
hier werden nur die superglobalen Arrays (
$_GET, $_POST, $_REQUEST usw.)
zugelassen. Die Auswirkungen von
register_globals=on werden rück-
gängig gemacht.
83>3+63=3/</8#3/&+<3+,6/8377/<

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required