| Die Sicherheit ist bei Entwicklung von Web-Anwendungen
ein sehr wichtiges Thema. Viele Entwickler wissen darüber leider
zu wenig bescheid oder denken nicht an die Folgen, die die Sicherheitslücken
entstehen lassen.
Gerade Web-Andwendungen sind mit einem hohen Bedrohungsptenzial
konfrontiert, da jeder Internetuser darauf Zugriff hat.
Es gelten daher die folgenden Empfehlungen (aus http://www.php-faq.de/q/q-sicherheit-parameter.html
von Kristian Köhntopp)
- Jede Form von Ping-Pong, also Wert-Weitergabe durch GET-Parameter,
HIDDEN-Variablen und dergleichen ist zu vermeiden. Auch durch
Codierung der Werte ist hier nichts zu erreichen. Stattdessen
sind Sessionvariablen zu verwenden. Nur die Session-ID wird von
einer Seite an eine andere Seite weitergereicht.
- Keinesfalls darf ein Programm Werte aus einer GET, POST oder
COOKIE-Quelle direkt verwenden. Jeder externe Wert ist einer Plausibilitätsprüfung
zu unterziehen, bevor er verwendet wird (Genau das wird in Wie
unterscheide ich böse Variablen von guten? näher beschrieben).
- Validierung von Eingabewerten muss serverseitig durch PHP geschehen.
JavaScript-Validatoren sind nicht vertrauenswürdig: Der Browser
des Anwenders führt diese Validatoren möglicherweise
nicht aus, auch dann, wenn er sich durch die User-Agent-Zeile
als JavaScript-fähiger Browser identifiziert. Ebenso muss
angenommen werden, dass die Referer-Header des Browsers möglicherweise
gefälscht sind. Man kann nicht annehmen, dass ein Zugriff
tatsächlich von einer bestimmten vorhergehenden Seite hierher
vermittelt wurde.
Zusammenfassend: Traue niemandem. Validiere allen Input oder stirb.
Globals
Wird ein Formular mit dem input-Feld "vorname" abgesandt,
so kann mittels PHP, sofern register_globals on sind, über
die Variable $vorname auf den Inhalt dieses Feldes zugegriffen werden.
Dadurch ist es für einen Angreifer auch sehr einfach andere
im Script verwendete (nicht initialisierte s. u.) Variablen überschreiben.
Durch das Abschalten der globals kann man nur mehr über $_GET["vorname"]
oder $_POST["vorname"] , je nach Versandart, auf den Inhalt
zugreifen. Man weiß also woher die Daten kommen. Dies sollte
jedoch nicht die einzige "Prüfung" von User-Daten
darstellen!
Wie schalte ich die Globals aus?
In der php.ini die Einstellung register_globals auf off sezten.
Initialisiere Variablen
Folgendes Script demonstriert wie einfach Sicherheit umzusetzten
ist:
<?php
if($user == "name" &&
$password == "password")
{
$logged_in = 1;
}
if($logged_in == 1)
{
// Code den nur eingeloggte User sehen dürfen
// ..
}
?>
 
Mit folgender einfachen
Ergänzung wäre es nicht mehr möglich mittels script.php?logged_in=1
sich ohne Username und ohne Passwort einzuloggen.
<?php
// Variablen initialisieren!!
$logged_in = FALSE;
if($user == "name" &&
$password == "password")
{
$logged_in = 1;
}
if($logged_in == 1)
{
// Code den nur eingeloggte User sehen dürfen
// ..
}
?>
Cross Site Scripting
Falls Eingabefelder nicht ausreichend geprüft werden, ist
es für einen Angreifer möglich eigene Scripte am Server
oder beim Client auszuführen. Untenstehendes Beispiel soll dies demonstrieren:
<?php
if(isset($_POST["name"])
{
echo $_POST["name"];
}
else
{
echo "<form method="POST" action="$_SERVER["PHP_SELF"]">";
echo "<input name="name" />";
echo "<input type="submit" />";
}
?>
<p>
Versuche in das Textfeld folgenden "Namen" einzugeben:
<SCRIPT>alert("Virus Warnung");</SCRIPT> oder
<p style="font-size: 150px">Hallo</p>.
Vor solchen oder ähnlichen Attacken kann man sich mit folgenden
Funktionen schützen:
| htmlentities() |
Wandelt alle Sonderzeichen in entsprechende
HTML-Codes um |
| htmlspecialchars() |
Bestimmte Zeichen haben in HTML eine spezielle
Bedeutung und sollten in HTML-Code dargestellt werden, um ihre
Bedeutung zu behalten. Diese Funktion liefert einen String zurück,
in dem manche dieser Konvertierungen durchgeführt wurden.
Die hier vorgenommenen Umwandlungen sind die nützlichsten
für die alltägliche Web-Programmierung. |
| strip_tags() |
Diese Funktion versucht, alle HTML- und
PHP-Tags aus str zu entfernen. Bei unvollständigen oder
sinnlosen Tags werden Fehler ausgegeben. Es wird die gleiche
Art der Tag-Engine wie bei der fgetss()-Funktion benutzt. |
| addslashes() |
Gibt einen String (Zeichenkette) zurück,
in dem bestimmten Zeichen ein Backslash "\" voran
gestellt wurde. Diese Funktion ist z.B. für Datenbankabfragen
wichtig. Die behandelten Zeichen sind das einfache und der doppelte
Anführungszeichen (' und "), der Backslash selbst
(\) sowie NUL (das Null-Byte). |
Noch mehr zur Überprüfung von Usereingaben: Wie
unterscheide ich gute von bösen Variablen?
Ausführliches Dokument zur Sicherheit:
http://www.christopher-kunz.de/uploads/media/Sicherheitsaspekte_in_PHP4_PHP5.Final_01.pdf
Schutz von e-mail-Adressen
Script aus dem Buch "Besser PHP programmieren" von Carsten
Möhrke. Modifiziert von Ingo Lacheiner:
<?php
function secure_mail($mail_adress,$query_string)
{
//Ja -> Java-Script öffnet Mail-Client und schließt Fenster wieder
if($query_string != "")
{
//ja -> Adresse auslesen und Mail senden
$mail = $query_string;
//Pipe mit at-Symbol ersetzen
$mail = str_replace("|","@",$mail);
//Java-Script mailto aufrufen und Fenster wieder schließen
$ausgabe = "<script typpe=\"text/javascript\">";
$ausgabe .="self.location.href=\"mailto:$mail\";";
$ausgabe .="self.close();";
$ausgabe .="</script>";
}
//Konvertierung für die Bildschirmausgabe
//Um den Query-String nicht anzuzeigen wird
//hier mittels preg_match alles vor dem ? gesucht und
//zurückgegeben, falls kein Query-String dann gesamte e-mail
//Adresse übernehmen
$suchmuster = "/.*(?=\?)/";
preg_match($suchmuster,$mail_adress,$ausgabe_mail);
if($ausgabe_mail[0] != "")
{
$mail = $ausgabe_mail[0];
}
else
{
$mail = $mail_adress;
}
//Bild statt @-Zeichen einfügen
$ausg_mail = str_replace("@","<img src=\"bilder/at_zeichen.gif\" width=\"12\" height=\"13\" border=\"0\">",$mail);
//Konvertierung für den "Link" (Quellcode)
$link = str_replace("@","|",$mail_adress);
//Ausgabe des Links
//ja -> an $ausgabe anhängen
if($query_string != "")
{
$ausgabe .= "<a target=\"_blank\" href=\"" . $_SERVER["PHP_SELF"] . "?adr=$link\">" . $ausg_mail . "</a>";
}
else
{
$ausgabe = "<a target=\"_blank\" href=\"" . $_SERVER["PHP_SELF"] . "?adr=$link\">" . $ausg_mail . "</a>";
}
return $ausgabe;
}
?>
 
·:: Zurück weiter ::· |