Ein kleines PHP-Listing oder ein PHP-Script-Schnipsel ist schnell geschrieben und lässt sich leicht in
einem bereits bestehenden HTML-Dokument einbinden, zum Beispiel um die durch ein Formular versendeten Daten auszugeben. Handelt
es sich dabei um einen Test, so spielt das Thema erst einmal eine untergeordnete Rolle, da Testseiten in der Regel der
Öffentlichkeit nicht zugänglich sind. Problematisch kann es hingegen werden, wenn ein Einsteiger den Empfang von per GET oder
POST übermittelten Daten mit einem einfachen Script-Schnipsel testet, dass Listing dann aber ohne zusätzliche Sicherung als
Webapplikation einsetzt.
Es sei angemerkt, nicht nur die ungesicherter Auswertung von per GET oder POST übermittelten Daten birgt ein Risiko in sich, da
es jedoch die gebräuchlichsten Request-Methoden sind, sollten diese beiden Request-Methoden zur Veran-schaulichung erst einmal
reichen.
In den Beispielen auf dieser Seite wurde PHP-Code in eine HTML-Seite eingebettet, um mit Hilfe der superglobalen $_GET Variable
die vom Formular versendeten Daten in Empfang zu nehmen. Die superglobale Variable $_GET enthält dabei ein assoziatives Array
mit allen Variablen und deren Werten, die von einem Formular als QueryString versendet und vom Script empfangen wurden. Beim
QueryString handelt es sich um den Teil einer URL, der hinter dem Fragezeichen beginnt und die einzelnen Variablen als Parameter
enthält. Wer möchte, kann sich mit Hilfe von print_r() oder var_dump() den Inhalt des in $_GET enthaltenen Arrays anzeigen
lassen.
Erstes Beispiel: In das Eingabefeld vom Formular wurde der String "Hallo Welt" eingegeben
und versendet:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Einstieg in PHP</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Style-Type" content="text/css"> </head> <body> <div style="width: 400px; text-align: center; margin: auto"> <?php print_r($_GET); // Ausgabe: Array ( [Name] => Hallo Welt ) ?> <form name="Eingaben" action="einstieg.php" method="get"> <input type="text" name="Name" value="" size="30"> <input type="submit" value="Senden"> </form> </div> </body> </html>
Um die von einem Formular versendeten und mit einem QueryString übermittelten Werte nicht nur als im
Array enthaltene Schlüssel und Werte anzuzeigen, sondern weiter zu verarbeiten oder formatiert auszugeben, kann auf die
einzelnen Werte wie folgt zugegriffen werden.
Zweites Beispiel: Formatierte Ausgabe von Werten. Nur für erste Tests geeignet, da Weiterverarbeitung
und Ausgabe ungesichert erfolgt!
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Einstieg in PHP</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Style-Type" content="text/css"> </head> <body> <div style="width: 400px; text-align: center; margin: auto"> <?php $einstieg = $_GET["Name"]; echo "<h1>".$einstieg."</h1>\n"; ?> <form name="Eingaben" action="einstieg.php" method="get"> <input type="text" name="Name" value="" size="30"> <input type="submit" value="Senden"> </form> </div> </body> </html>
Für einen einfachen Test mag das letzte Listing bereits völlig ausreichen, von der Verwendung im Web
wird hingegen dringlich abgeraten, da gleich mehrere Schwachstellen enthalten sind.
Die erste Unzulänglichkeit besteht darin, dass vom Script nicht kontrolliert wird, ob ein QueryString mit Parametern und Werten
übergeben wurde. PHP würde, je nach Einstellungen in der php.ini, mit einer E_NOTICE antworten, insofern keine Werteübergabe
erfolgte.
Eine E_NOTICE ist noch kein Fehler, könnte aber einen Hinweis auf mögliche Fehler enthalten. Vor der ersten Benutzung des
Formulars und beim ersten Aufruf der Seite kann ja noch kein übergebener Wert vorhanden sein und somit wäre eine E_NOTICE erst
nach der ersten Benutzung des Sende-Buttons berechtigt. Besser ist es hingegen, mit isset() abzufragen, ob ein Parameter
übermittelt wurde und mit empty() zu kontrollieren, ob dem Parameter ein Wert zugeordnet wurde und falls nicht einen eigenen
Hinweis auszugeben. Nebenbei bemerkt, mit dem Ausrufezeichen vor empty erfolgt eine Negierung, womit nichts anderes gemeint ist,
als dass der übermittelte Parameter keinen leeren Wert String oder Null-Wert enthalten darf. Für die Abfrage von isset() und
empty() wird ein if-Statement verwendet, dessen Aufbau sich in den vorgestellten Script- und Programmier-sprachen gleicht:
if (Bedingung) { // oder mehrere Bedingungen gewünschte Anweisung; // z.B. Ausgabe } else {alternative Mitteilung oder alternative Anweisung;}
Eine E_NOTICE kann noch relativ harmlos sein und in der Mehrheit der Fälle sind sie es auch, doch, wie
im obigen Beispiel, Werte ungeprüft zu übernehmen und auszugeben, kommt schon sträflichen Leichtsinn gleich. Theoretisch
könnte jeder beliebige Bösewicht den Wert austauschen und stattdessen Name => Schadcode übergeben. Um die Einschleusung
von Schadcode zu erschweren, sollte der übergebene Wert kontrolliert und gefiltert werden.
Im nächsten Beispiel hilft dabei die PHP-Funktion preg_replace(), die mit Hilfe eines regulären Ausdrucks nach allen Zeichen
sucht, die keinem Buchstaben und keiner Zahl entsprechen und diese Zeichen entfernt. Wird nun die Ausgabe zusätzlich noch mit
htmlentities() abgesichert, so ist das Listing bereits recht sicher.
Drittes Beispiel: Mit preg_replace und htmlentities abgesichertes Listing.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Einstieg in PHP</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Style-Type" content="text/css"> </head> <body> <div style="width: 400px; text-align: center; margin: auto"> <?php if (isset($_GET["Name"]) and !empty($_GET["Name"])) { $einstieg = trim($_GET["Name"]); $einstieg = preg_replace("/[^a-zA-ZäöüÄÖÜß0-9]/"," ",$einstieg); echo "<h1>".htmlentities($einstieg, ENT_QUOTES)."</h1>\n"; } else { echo "Null Nachrichten!\n"; } ?> <form name="Eingaben" action="einstieg.php" method="get"> <input type="text" name="Name" value="" size="30"> <input type="submit" value="Senden"> </form> </div> </body> </html>
Es sei angemerkt, eine absolute Sicherheit gibt es nicht und ein Angreifer, der auf einen Weg nicht weiter kommt, wird sich gegebenenfalls nach einem anderen Weg umsehen. Mehr zum Thema Syntax und Sicherheit gegebenenfalls zu einem späteren Zeitpunkt.
Syntax und Sicherheit – Teil I « zurück
Einstieg in PHP
Übersicht
Diverse Themen