Sicheres Programmieren
– Traue niemals den Eingaben des Benutzers!
Speichern Sie fremde Benutzereingaben
nie ohne eine
Überprüfung in einer Datenbank oder in einer Datei ab.
Vertrauen Sie
keinen Werten, die über Benutzereingaben,
den URL oder Cookies in das PHP-Skript gelangen.
Alle externen Parameter, selbst wenn sie aus
versteckten Feldern oder
Auswahlmenüs (Auswahllisten) kommen, müssen einer Plausibilitätsprüfung
unterworfen werden, bevor sie im Programm verwendet werden.
Manche Browser wie etwa
Safari und
Firefox erlauben überdies bereits von Haus
aus oder durch Erweiterungen das direkte verändern des Quellcodes. Formular-
manipulationen sind dadurch sogar noch einfacher.
Inhalt dieser Seite:
• Validieren – die Datenanalyse
Die Validierung ist Teil der Qualitätssicherung und bezeichnet die Prüfung von
Werten auf bestimmte Eigenschaften wie etwa, ob der Wert eines bestimmten
Datentyps, einer Datendomäne oder eines Datenformats entspricht.
Es ist also ein analysierender Vorgang, der als Ergebnis eine Aussage bestätigt
oder widerlegt. Solche Eigenschaftsprüfungen könnten mit Fragen wie „entspricht
der Wert einer positiven Ganzzahl?“ oder „enthält der Wert keiner Zeichen der
Zeichenmenge X?“ ausgedrückt werden.
• Überprüfen Sie ob bestimmte Zeichenfolgen in der Benutzereingabe vorhanden
sind
if (strstr($_POST["url"], "http://")) { … oder
if (preg_match('_(<a\s+href\s*=.*){3,}|(http://[a-z0-9-./\_]{6,}.*){2,}_is',
$_POST["textarea"])) { …
• Überprüfen Sie auch Zahlen ob diese sich im erlaubten Bereich befinden
und ob tatsächlich eine Zahl eingegeben wurde
is_numeric($_POST["zahl"]) .
Weitere Prüfungen: ctype_digit(), is_bool(), is_null(), is_float(), is_int(),
is_string(), is_object(), is_array().
• Kürzen Sie Benutzereingaben
<input type="text" name="text" size="25" maxlength="30">
…
$text = substr($_POST["text"], 0, 30);
• Achten Sie auf Mindestlängen und Maximallängen
if (strlen( $_POST["eingabe"]) < 5) { …
• Überprüfen Sie das Datum auf Gültigkeit
if (checkdate($monat, $tag, $jahr)) { …
Überprüfen mit Regulären Ausdrücken
• Postleitzahl mit Fünf Ziffern
if (!preg_match("/^\d{5}$/", $_POST["plz"])) {…
• Überprüfen Sie die E-Mail-Adresse auf Gültigkeit
$_pat = "^[_a-zA-Z0-9-]+(.[_a-za-z0-9-]+)*@([a-z0-9-]{3,})+.([a-za-z]{2,4})$";
if (preg_match("|$_pat|i", $_POST["email"])) { …
• Überprüfen Sie die URL-Adresse auf Gültigkeit
$_pat = "#^(http|https)+(://www.)+([a-z0-9-_.]{2,}\.[a-z]{2,4})$#i"
if (preg_match($_pat , $_POST["url"])) { …
• Überprüfen Sie auf nur Zahlen
if (preg_match("#^[0-9]+$#", $_POST["zahlen"])) { …
• Überprüfen Sie auf nur Buchstaben
if (preg_match("/^[ a-zA-ZäöüÄÖÜß]+$/i", $_POST["buchstaben"])) { …
• Überprüfen Sie auf Spam
Enthält ein einzeiliges Formularfeld Zeilenubrüche handelt es sich meistens
um Spam.
if (preg_match('_[\r\n]_', $_POST["name"])) { …
• Filtern – das Trennen von Gut und Schlecht
Das Filtern dient der Trennung von erlaubten und unerlaubten
Werten, wobei nur die erlaubten Werte durchgelassen werden.
Man sollte sich nicht nur auf gefilterte Nutzereingaben verlassen,
sondern auch nochmals beim Schreiben in die Datenbank (oder
Datei) die Eingaben überprüfen.
• Filtern Sie mit
strip_tags($_POST["name"])
HTML-Tags heraus
oder lassen Sie mit
preg_match("/[a-zA-Z0-9.äöüÄÖÜß]/", $_POST["name"])
nur bestimmte Zeichen durch.
• Filtern Sie Leerzeichen und Zeilenumbrüche (Metazeichen) am Zeilenanfang und
Zeilenende
$text = trim($_POST["text"]);
• Filtern Sie Zeilenumbrüche des Textarea-Tags
$textarea = str_replace(array("\n", "\r"), "", $_POST["textarea"]);
• Filtern einer „E-Mail Header Injection”
preg_replace( '((?:\n|\r|\t|%0A|%0D|%08|%09)+)i' , "", $_POST["email"]);
• Filtern einer Variablen durch einen spezifischen Filter
filter_var() (
PHP 5)
Die eingebauten PHP-Filter repräsentieren, zumindest gegenüber gar keinen
Filtern, einen großen Fortschritt, den bisher viele Web-Programmierer noch gar
nicht entdeckt haben.
filter_var("test@demo.xy", FILTER_VALIDATE_EMAIL)
filter_var("www.test.xy", FILTER_VALIDATE_URL)
filter_var($_POST["name"], FILTER_SANITIZE_STRING)
filter_var($_POST["zahl"], FILTER_VALIDATE_INT)
• Filtern Sie Spam und "schlechte Wörter" durch eigene Funktionen
Siehe
Badwordfilter
• Verwenden Sie
switch/case wenn Sie eine Navigation oder Datenbank-
Anweisungen über $_GET oder per $_POST steuern wollen.
Siehe
Anweisungen über einen Link senden
switch ($_POST["do"]) {
case "delete":
$do = "delete";
break;
case "reset":
$do = "reset";
break;
case "edit":
$do = "edit";
break;
default:
$do = "none";
}
• Beim Erstellen von Filterfunktionen ist das „Whitelisting” bestimmter Zeichen,
also das explizite Zulassen, stets sicherer als das „Blacklisting”, also das explizite
Verbieten, weil es nur selten gelingt, wirklich alle potenziell problematischen
Werte zu erfassen.
$whitelist = array("delete", "reset", "edit");
if (in_array($_GET["do"], $whitelist)) {
$do = $_GET["do"];
}
• Lassen Sie sich lediglich den reinen Dateinamen mit
$_GET übermitteln
und setzen den Verzeichnispfad fest in der PHP-Datei ein.
<?php
$verzeichnis = "/ein/anderes/verzeichnis" . $_GET["datei"] . ".php";
if (file_exists($verzeichnis)) {
include $verzeichnis;
}
?>
• Dateipfad prüfen
if (strpos($_GET['dateiname', '..') { … Überprüfen auf einen Verzeichniswechsel.
if (preg_match("=daten/=", $_GET["dateiname"])) { … Ist das Verzeichnis
"
daten/" vorhanden.
• Dateipfad, Dateiname und Dateiendung (
extension) ermitteln
$pfad = pathinfo("/www/htdocs/index.php");
echo $pfad["dirname"] .
$pfad["basename"] .
$pfad["extension"];
• Maskieren – das Entschärfen von Metazeichen
Das Maskieren bezeichnet das Entwerten von Metazeichen, so dass diese ihre
besondere Funktion verlieren. Dies geschieht entweder durch setzen eines
zusätzlichen Maskierungszeichens oder durch Ersetzten dieser Zeichen. Das
Maskieren ist immer dann notwendig, wenn Werte unbekannten Typs oder
Formats (es fand also keine angemessene Validierung oder Filterung statt oder es
können immer noch Metazeichen enthalten sein) an ein Subsystem (z.B.:
MySQL)
übergeben oder an den Client (Browser) ausgegeben werden.
• Bauen Sie dazu Maskierungen wie zum Beispiel:
mysql_real_escape_string($_POST["name"])
in Ihr Script mit ein.
Oder
quotemeta($tring) , der Inhalt von
$tring wird mit einem Rückstrich
("Backslash", \) vor jedem Vorkommen von
. \ + * ? [ ^ ] ( $ ) versehen ("quoten") und zurückgegeben.
• Verwenden Sie für HTML-Ausgaben
htmlspecialchars() oder die
urlencode()-
Funktionen (bei URL-Komponenten).
• Inhalt ersetzen
In diesen Beispiel werden deutsche Umlaute ersetzt.
$trans = array("Ö" => "Ö", "ö" => "ö", "Ä" => "Ä",
"ä" => "ä", "Ü" => "Ü", "ü" => "ü", "ß" => "ß");
$_POST["text"] = strtr($_POST["text"], $trans);
Oder mit
str_replace(array("1", "2", "3"), array("eins", "zwei", "drei"), $_POST["text"]);
• Bei MySQL mit Hochkommata arbeiten
… WHERE id='". $_POST["text"] . "' …
• Zahlenwert in Integer (Datentyp) umwandeln
$limit = (int) $_POST["limit"];
• Verzeichnisse und Dateien mit .htaccess sperren
Zugriff auf Dateien sperren (nur
include, require, etc. zulassen).
Verschieben Sie alle Dateien, die nur über das PHP-Script aufgerufen werden sollen, in ein Verzeichnis.
Innerhalb dieses Verzeichnis stellen Sie eine Textdatei mit
folgendem
Inhalt ein (beim Apache heißt diese Datei „
.htaccess”)
mit folgender
Syntax aus:
Order Deny,Allow
Deny from all
Das „Order Deny,Allow” heißt, dass die „deny” (Verbots) Regel
vor der „allow”
(Erlaubnis) Regel abgearbeitet wird.
•
Eigene Fehlerseiten definieren*
ErrorDocument 401 http://www.domain.xy/401.html
ErrorDocument 403 http://www.domain.xy/403.html
ErrorDocument 404 http://www.domain.xy/404.html
(401 = Unauthorized, 403 = Forbidden, 404 = File Not Found,
Server
Fehlermeldungen)
Oder alle Fehlermeldungen vom Apache einfach zur Startseite weiterleiten.
Die Datei „.htaccess” sollte im obersten Verzeichnis ihrer Webpräsenz liegen.
*
Es kann passieren, dass die Sache nicht funktioniert. Dann hat vielleicht Ihr Provider die
Möglichkeit des Anlegens von .htacess-Dateien auf dem Server unterbunden.
•
Bilder / Grafiken und andere Dateien durch das direkte verlinken von
anderen Webseiten schützen.
So sind Sie sicher, das Ihre Bilder nicht direkt verlinkt werden und unerwünschter
Traffic (Datentransfer) erzeugt wird.
<Files ~ "\.(gif|jpe?g|png|zip)$">
ErrorDocument 403 http://www.domain.xy/bilder/bilderdieb.png
SetEnvIfNoCase Referer "^http://www.domain.xy" local_ref=1
SetEnvIfNoCase Referer "^http://domain.xy" local_ref=1
SetEnvIfNoCase Referer ^$ local_ref=1
Order Allow,Deny
Allow from env=local_ref
</Files>
Das Verzeichnis Ihrer Domain eintragen!
•
PHP in HTML-Dateien verstecken!
Eine Möglichkeit ist mittels der .htaccess-Direktive so zu konfigurieren, dass dieser verschiedene Dateitypen (z.B.: .htm) durch PHP parst.
# HTML-Dateien parsen
AddType application/x-httpd-php .htm .html
Sie müssen dann Ihre PHP-Dateien nach den obigen Dateierweiterung umbenennen.
•
Verzeichnislisting (Directory Indexing, Verzeichnis-Browsing)
Verzeichnislisting ist eine Funktion des Webservers, die, wenn die übliche
Standarddatei (
index.html, home.html, default.htm) fehlt, automatisch alle
Dateien im Verzeichnis zeigt

, dann kann
das Listing Informationen enthalten,
die
nicht für die Öffentlichkeit bestimmt sind.
•
Verzeichnislisting verhindern
DirectoryIndex index.php index.html
A) Fügen Sie in allen Verzeichnissen eine
index.php oder
index.html
Inhalt der
index-Seite: Entweder ganz normaler Inhalt oder eine Weiterleitung
(mit
Link, Meta-Tag oder über
header()) zur gewünschten Seite.
Somit sind auch Verweise auf Verzeichnisse möglich (
www.websei.de/info/bilder)
B) Sie können festlegen, ob der Apache einen Fehler zurückgeben soll, wenn sich
keine Startseite in einem Verzeichnis befindet, oder ob er den Inhalt des
Verzeichnisses ausgeben soll.
# Inhalt ausgeben:
Options +Indexes
# oder Fehler ausgeben:
Options -Indexes
C) Möglicherweise bietet Ihr Webspace-Provider eine Option an, die es erlaubt
Verzeichnislisting abzuschalten.
• Chmod - Lese- und Schreibrechte vergeben
Mit dem Befehl Chmod (englisch:
change mode) werden im UNIX Umfeld
Lese-, Schreib- und Ausführungsrechte von Dateien und Verzeichnisse gesetzt.
Viele Webserver, auf denen Ihre Daten liegen, laufen mit UNIX.
chmod ("/verzeichnis/datei", 0644);
• Durch das falsche setzen von Chmod können unberechtigte Benutzer (vom
selben Server) Zugriff auf Ihre Dateien erhalten, beachten Sie diesen Umstand
und seien Sie entsprechend vorsichtig. Die Berechtigungen Ihres obersten
Verzeichnisses sollten Sie deshalb
niemals ändern, bzw. niemals mit vollen
Rechten (Chmod 777) versehen. Mit dem „obersten Verzeichnis” ist Ihr
Account-Start-Verzeichnis gemeint. Mehr dazu unter
Schreib- und Zugriffsrechte
CHMOD-Kalkulator
(Chmod richtig einstellen)
• Sicherheitsoptionen in der php.ini
Ein Feature von PHP zur Erhöhung der Sicherheit ist die Konfigura-
tion von PHP mit
register_globals = off. Mit Deaktivierung der
Möglichkeit, irgendeine vom Benutzer übertragenen Variable
in den PHP Code zu injizieren, können Sie die Anzahl „vergifteter”
Variablen reduzieren, welche ein potentieller Angreifer zufügen könnte.
•
allow_url_fopen = off legt fest, ob man Dateien öffnen kann (z.B. mit fopen()) die nicht auf dem Server liegen.
•
allow_url_include = off sorgt dafür, dass PHP-Skripte nur lokale Dateien des Servers einbinden können (ab PHP 5.2).
•
safe-mode = on bewirkt unter anderem, dass der PHP-Prozess nur noch auf Dateien und Verzeichnisse zugreifen darf, die dem Nutzer gehören.
•
magic_quotes_gpc = on escaped alle Single-quotes ('), Double quotes (") , Backslashes (\) und NULL-Zeichen automatisch mit einem Backslash.
•
phpinfo() Zeigt eine grosse Anzahl von Informationen über die aktuelle
Konfiguration von PHP an. Unter anderem die Optionen während des Kompilierens
und die Erweiterungen, die PHP Version, Informationen über den Server, die PHP
Umgebung, Version und Informationen zum Betriebssystem, Pfade, Haupt- und
lokale Werte der Konfigurationsoptionen.
<?php phpinfo(); ?>
• Passwörter – der Schlüssel zu Ihren Daten
Schützen Sie Ihre Formulareingaben, erlauben Sie Einträge nur über eine
Authentifizierung für Berechtigte (Passwort-Abfrage).
• Verschlüsseln Sie
alle Passwörter die Sie speichern wollen.
$passwort = md5("Passwort"); oder
$passwort = sha1("Passwort");
• Verwenden Sie kryptische Passwörter
Eigentlich sollte man das nicht mehr erwähnen müssen:
Passwörter für Web- oder Datenbankserver, die Sie in einem Lexikon
finden können, sind so gut wie geknackt.
Die „billigsten” Passörter sind:
passwort, password, user, admin, Vorname, Nachname, Name der Homepage, Thema der Homepage, …
• Automatische Texteingabe in Formularfeldern verhindern.
Moderne Browser haben eine autom. Eingabefunktion die schon einmal
eingegebene Daten in ein Formularfeld wieder einfügen.
Es gibt Situationen, in denen es sinnvoll ist, das autom. ausfüllen zu verhindern,
wenn zum Beispiel jemand anders vor dem PC sitzt.
<form autocomplete="off">
oder direkt im HTML-Tag
<input type="text" autocomplete="off"> (Leider noch
nicht
W3C gemäß, dies soll sich aber mit den „
Web Forms 2.0” ändern).
• Dateiupload – Fremde Daten auf Ihrem Server
Lässt man dem Besucher die Möglichkeit Dateien hochzuladen, so muss gewähr-
leistet
werden, dass diese Dateien nicht auf das restliche System anwendbar sind.
Das funktioniert beispielsweise in dem man nur bestimmte
Dateitypen erlaubt.
Das Problem ist, dass jemand beispielsweise eine PHP-Datei hochladen könnte
um diese dann extern aufzurufen, das würde dazu führen, dass jene Datei
auf das restliche System eingreifen könnte.
• Überprüfen des
MIME-Types und der Dateigröße
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)) { …
• Mit
getimagesize prüfen, ob es sich um ein Bild handelt (die zurückgelieferten Werte auswerten!).
• Verschieben Sie die hoch geladene Datei in ein anderes Verzeichnis mit
begrenzten Schreibrechten (Chmod) und geben Sie der Datei einen neuen Namen.
• Bieten Sie eine Upload-Möglichkeit möglichst nicht öffentlich für
Jedermann an,
sondern erlauben Sie das nur über eine Authentifizierung für Berechtigte.
• CAPTCHAs – den Schlüssel im Bild!
(
Completely Automated Public TuringTest to Tell Computers and
Humans Apart) Vor einiger Zeit hat es sich weiträumig
durchgesetzt, sog. CAPTCHAs zu verwenden. Hierfür werden fast
immer Zahlen oder Wörter möglichst unleserlich in
einem Bild
dargestellt, das vermeintlich nur von Menschen entziffert werden
kann.
Durch die Eingabe der Zahl bzw. des Wortes im Klartext wurden Menschen von
Maschinen unterschieden und Eingaben von letzteren abgewiesen.
Es gibt bereits spezialisierte Programme, die grafische CAPTCHAs verschiedenster
Ausprägungen knacken oder sich auch bei verbreiteten Webforen automatisch
registrieren, die Antwort-E-Mail auswerten und danach mit einem regulären
Benutzerkonto Beiträge schreiben. Zur Zeit wird auch an die Verwendung von Video-CAPTCHAs gearbeitet.
•
Andere Möglichkeiten: Speicherung der IP-Adresse; Speicherung von Cookies;
Ändern des Namens im Input-Tag; Zeitabhängige eingaben; Rechenaufgabe vom
Benutzer ausfüllen lassen; Versteckte Eingabefelder (mit CSS);
Einen
Bestätigungs-Link per E-Mail senden (Zeitabhängige Aktivierung);
Formulare mit
AJAX; Formular absenden mit JavaScript (
onClick="form.submit()");
… Der Fantasie sind keine Grenzen gesetzt, solange der Besucher mit macht ;)
• Datei robots.txt – Infos für Webcrawler
Beim Auffinden einer Webseite von einem Webcrawler wird zuerst die Datei
„
robots.txt” (kleingeschrieben) gelesen. In dieser Datei kann festgelegt
werden, ob und wie die Webseite von einem Webcrawler besucht werden darf.
Die Datei robots.txt ist eine Textdatei in einem einfach lesbaren Format.
# Diese Verzeichnisse/Dateien sollen nicht durchsucht werden
User-agent: *
Disallow: /geheim.php
Ein Ausgrenzen bestimmter Teile einer Webpräsenz durch robots.txt garantiert keine Geheimhaltung.
Genauso wenig schützt der Meta-Tag
<meta name="robots" content="noindex" /> davor.
• User-Agent – Was der Browser verrät
Wenn man mit einem Browser im Internet surft, wird meist mehr verraten,
als dem Besucher lieb ist.
$_SERVER["HTTP_USER_AGENT"];
Beispielsweise:
CCBot/1.0 (+http://www.commoncrawl.org/bot.html)
Auch diese Infos können via Browser manipuliert werden.
• Richtige Browser sollten immer einen User-Agenten mitschicken,
also selbst bekanntgeben, wer sie sind. Ist dies nicht der Fall, ist der
Besucher meist ein Bot (Webcrawler).
• Den USER_AGENT Mozilla auszusperren sollte man tunlichst vermeiden,
da die meisten Browser sich als Mozilla identifizieren.
• Sicherheitslücke: Fehlermeldungen
Lassen Sie PHP oder MySQL-Fehlermeldungen
nie im produktiven
Einsatz anzeigen. Angreifer gewinnen durch diese Fehlermeldungen
hilfreiche Tipps! Anzeige von:
Pfad und
Name der Datei,
Script-Fehler und
Zeilennummer.
Solange man seinen Quelltext debuggen muss, ist dieser Ansatz zu
begrüßen, doch sobald die Webseite in der finalen Fassung
vorliegt, ist der Einsatz von
error_reporting(),
mysql_error() etc. eher als eine
Sicherheitslücke zu bezeichnen
• Die folgende Anweisung verhindert, dass Angreifer gezielt Fehlermeldungen provozieren können.
error_reporting(0);
Mehr dazu unter
PHP-Fehlermeldungen.
• Kommentare im HTML-Quelltext
Eine Schwachstellle liegt vor, wenn eine Website sensible Daten zum Beispiel
Kommentare der Entwickler, die einem Angreifer helfen das System zu
missbrauchen, ausgibt.
• Sicherheitslücke: Cross-Site Scripting (XSS)
Wie Formulare manipuliert werden können
Manipulationen von Formularen ist einfacher als manch einer sich das denkt.
Die einfachste Möglichkeit, ein Formular zu manipulieren, ist, den HTML-Quellcode
des Formulars zu kopieren und in einer lokalen Datei zu speichern. Diese kann
dann beliebig verändert werden. Dadurch ist es auch möglich, dass Schadcode
dort injiziert wird, wo es im Originalformular gar nicht möglich war (beispielsweise
bei versteckten Formularelementen, Auswahllisten, Checkboxen etc.).
PHP_SELF und Cross-Site-Scripting
Das superglobale Array
$_SERVER beinhaltet verschiedene Informationen über die
Ausführungsumgebung und den Server. Sie umfasst unter anderem das Element
$_SERVER['PHP_SELF']. Diese global verfügbare, vordefinierte Variable liefert den
Dateinamen des jeweiligen Skriptes, welches gerade ausgeführt wird, wie zum
Beispiel
echo $_SERVER['PHP_SELF']
• Die einfachste Gegenmaßnahme beim Einsatz von
PHP_SELF besteht darin, die Variable immer zu bereinigen.
echo filter_var($_SERVER['PHP_SELF'], FILTER_SANITIZE_STRING); (PHP 5)
• Verwenden Sie anstelle von
$_SERVER["PHP_SELF"] besser
$_SERVER["SCRIPT_NAME"] oder gleich den Dateinamen.
• Sicherheitslücke: Kontaktformular (E-Mail-Header-Injection)
Die "E-Mail-Header-Injection" ist eine Methode, E-Mail-Kopfzeilen über ein
Kontaktformular-Skript in eine E-Mail zu "injizieren". Spammer können auf diese
Art Kontaktformular-Sendeskripte zum massenhaften Verteilen von Spam
missbrauchen. Besonders ärgerlich für den Besitzer des Kontaktformulars ist, dass
Spammer seine E-Mail-Adresse als Absender des Spams angeben können.
• Gegenmaßnahmen siehe »
Filtern – das Trennen von Gut und Schlecht
•
Mehrere E-Mails per BCC verschicken
In einer BCC-E-Mail (Blind-Carbon-Copy) finden Viren höchstens zwei E-Mail-Adressen. In einer CC-E-Mail (Carpon-Copy) können es buchstäblich Hunderte von Adressen sein.
CC-E-Mails mit vielen E-Mail-Adressen sind ein gefundenes Fressen für Spammer. Mit BCC-E-Mails tragen Sie also einen Beitrag zur Bekämpfung von Spam bei.
• Sicherheitslücke: PHP Referrer
Der Referrer ist beliebig manipulierbar aber an sich ungefährlich.
Schaden anrichten kann er wenn Ihr Auswertungsscript anfällig z.B. gegen HTML-Injection ist.
Manche Webseiten führen irgendwo auf der Seite eine Liste: „
verlinkt von”
Wenn dort ungeprüft der Referrer verwendet wird kann man einen Referrer
in der Art:
<script type="text/javascript">location.href="http://SeiteMitVirus.xy"</script>
einschmuggeln. Und künftig wird jeder Besucher der Seite (sofern Javascript
aktiv ist) auf
http://SeiteMitVirus.xy umgeleitet.
• Wenn Sie mit dem Referrer arbeiten, dann setzen Sie
strip_tags() dazu ein um
HTML-Spam im
Referrer zu löschen.
• Referrer nicht zu sicherheitsrelevanten Zwecken auf einer Website verwenden.
• Sicherheitslücke: Fremde Inhalte
Viele Webseiten haben auf Ihrer Seite Inhalte von anderen Seiten die
z.B.: das Wetter, aktuelle News, Werbebanner etc. anzeigen, diese
werden oft als JavaScript, Frame, Flash oder XML-Datei bereit gestellt.
Der Betreiber hat hier wenig Möglichkeiten um schadhaften Code zu filtern.
• Wenn Sie eine
Log-in-Seite haben, sollten Sie auf die Anzeige fremder
Inhalte verzichten.
• CSS und JavaScript binden verlinkte Grafiken auch mit einer anderen
Dateiendung ein.
background-image: url(datei.php);
Was auf der einen Seite nützlich ist kann auch eine Gefahrenquelle sein.
• Sicherheitslücke: Ajax und XMLHttpRequest
Der Begriff Ajax steht für „
Asynchronous Javascript and XML” und bezeichnet ein
Konzept der asynchronen Datenübertragung zwischen einem Server und dem
Browser. Die Besonderheit dabei ist, dass es damit möglich ist, innerhalb einer
HTML-Seite eine HTTP-Anfrage durchzuführen, ohne die Seite komplett neu laden
zu müssen.
Die Kombination aus massivem Javascript-Einsatz und Interaktivität bringt
zahlreiche Gefahren mit sich, die sowohl für Betreiber als auch Benutzer von
Web-2.0-Applikationen fatale Folgen haben können. Über geschickte Eingaben
kann ein Angreifer zum Beispiel die Nutzerdatenbank manipulieren, einen Server
für längere Zeit lahm legen oder Inhalte verändern.
• JavaScript sollten Sie niemals als Sicherheitsmaßnahme zur Validierung der
Formulareingabe nutzen, weil diese Methode leicht ausgehebelt werden kann.
Verwenden Sie JavaScript nur um den Benutzer auf seine Fehler im Formular hinzuweisen.
• Sicherheitslücke: MySQL-Datenbank
Bei der Installation von MySQL werden die Datenbanken „
mysql” und „
test”
angelegt. Erhält ein Unbefugter Zugriff auf die Datenbankverzeichnisse, kann er
diese kopieren und erhält so unbeschränkten Zugriff auf die darin gespeicherten
Daten.
• SQL Injectionen gehören zu den gefährlichsten und weitverbreitesten Fehlern
bei Webanwendugen. Besondere Bedeutung fällt dabei der Datenbank „
mysql” zu.
Hier werden sämtliche Berechtigungen gespeichert. Fällt diese Datenbank in
fremde Hände, ist es für einen Neugierigen ein leichtes, mit der richtigen
Kombination aus Host, Benutzerkennung und Passwort unbemerkt Daten
auszuspionieren oder diese zu manipulieren.
• Sämtliche Datenbanken sollten daher nur für den MySQL-Prozess zugänglich
sein. Ein häufiges Problem nach Abschluss der Installation ist das fehlende
Passwort für den Datenbank-Administrator „
root”. Natürlich soll nicht nur der
Datenbankadministrator Zugriff auf die von MySQL verwalteten Daten erhalten.
Vielmehr gilt es, die einzelnen Anwendungen mit den richtigen Rechten
auszustatten, um ihre Aufgaben effizient zu erfüllen.
• Ein Angreifer, der mit einem Formular zum Einloggen konfrontiert wird, spekuliert
über die Weise, wie die Abfrage zur Validierung des Benutzernamens und des
Passwortes funktioniert. Ein Blick in den HTML-Quelltext gibt meist schon zu viel
preis. Besonders leicht hat es der Angreifer, wenn die gewählten Namen leicht zu
erraten sind, etwa wenn der Benutzername in der Variable
$benutzername und
das Passwort in der Variable
$passwort gespeichert werden und die zugehörigen
Datenbankfelder genauso heißen.
• Sicherheitslücke: Datei-. und Verzeichnisnamen
Viele Datei-. und Verzeichnisnamen laden zum „hacken” gerade zu ein:
login, intern, secure, geheim, privat, …
Verzichten Sie lieber auf solche und andere auffällige Namen.
»
10 Regeln zu Dateinamen
• Der Inhalt der Seite, falls diese durch eine Suchmaschine indexiert wird,
kann Text enthalten der nicht für eine Indexierung bestimmt ist.
Abhilfe schafft hier »
robots.txt (die Suchmaschinen müssen sich aber nicht
unbedingt daran halten!) oder ein Verzicht auf bestimmte Schlagwörter.
• Halten Sie Ihren Code unter Verschluss!
Wenn Sie „öffentlichen” Code verwenden (z.B. aus Skriptarchiven),
gehen Sie das Risiko ein, daß systematisch nach diesem Code
gesucht werden kann.
Wenn Sie Ihren eigenen Code veröffentlichen (z.B.: in Foren),
gehen Sie das Risiko ein, daß potentielle Hacker darin gezielt auf
die Suche nach Ihren kleinen Sünden gehen.
Wenn Sie öffentlichen Fremdcode verwenden wollen, kann sich die Umbenennung
der Skripte bezahlt machen.

Auch hier finden Sie
keinen fertigen Code um Ihre Webseite zu schützen,
dieser muß für jede Seite individuell angepasst werden.
• Formular-Spam – Kostenlose Werbung
Hier weitere Tipps zu den oben genannten Möglichkeiten um Formular-Spam
(Kommentar-Spam) zu vermeiden:
• Enthält das Mitteilungsfeld sehr viel HTML-Code oder mehrere URLs, handelt es
sich meistens um Werbung
if (substr_count($_POST["eingabe"], "http:") > 3 ) { …
• Enthält das erste (in der Regel einzeilige) Formularfeld Zeilenumbrüche, deutet
das auf einen Versuch von
E-Mail Header Injection hin.
if (substr_count($_POST["email"], '\n') > 0 ) { …
if (substr_count($_POST["email"], '@') > 1 ) { …
• Nach senden des HTML-Formulars Stellen Sie die Informationen nochmals dem
Benutzer zur Bestätigung zusammen (Vorschau). Erst Durch Betätigung mittels
Formulars wird dann eine Mail ausgelöst.
• Speichern Sie die Formulardaten die Besucher machen in einer Datei ab.
Damit besteht die Möglichkeit, zu erkennen, wann Spamversuche stattfinden.
Bei „Spam” werten Sie die Datei aus und ergreifen Gegenmaßnahmen.
• Verwenden Sie in Ihrem Forum oder Blog
BBCode (
Bulletin Board Code) statt
HTML. Diese können anders als HTML-Tags keine Attribute wie zum Beispiel
<img src="bild.gif" onclick="location.href='seite.xy';"> enthalten. Mehr Infos
zum BBCode auf
de.wikipedia.org/wiki/BB_Code
• Prüfen Sie ob eine doppelte Eintragung durch falsche bzw. mißbräuchliche Browserbenutzung (z.B.: „Reload”) möglich ist und treffen Sie dann entsprechende Vorkehrungen bei der Konstruktion der Datenverarbeitung.
• Formulare – die Fehlerquelle schlechthin
Fehleingaben in Formularen sind immer möglich und wenn es sich nur um Schreibfehler des Benutzers handelt.
• Vermeiden Sie Fehlerquellen, zum Beispiel: Eingabe eines bestimmten
Datumsformats mit den
Input-Tag. Verwenden Sie dafür Auswahllisten,
je eine für
Tag, Monat und
Jahr.
• Zukünftige Browser sollen mehr Eingabemöglichkeiten in Formularen bieten
HTML 5 - Die neuen Input-Elemente (Web Forms 2.0) Auch hier gilt es dann
(trotz Browser-Eingabewertprüfung) die Angaben serverseitig nochmals zu prüfen.
• Tipps
• Geben Sie absichtlich falsche Werte ein — bricht das Script mit einer Fehler-
meldung ab oder kommt es zu irgendwelchen Fehlverhalten müssen Sie diese korrigieren.
• Testen Sie Formulare gründlich auf Benutzbarkeit und Barrierefreiheit.
• Oft sind Formularfelder zu klein um die Daten vernünftig einzugeben.
• Formularfelder sollten nicht nebeneinander sondern untereinander stehen.
• Niemand füllt gerne Formulare aus.
Beschränken Sie die Angaben in den Formularen auf das nötigste (nur Pflichtfelder).
So ist es beispielsweise unnötig, bei der Bestellung in einem Online-Shop Angaben
wie den Geburtsort oder dergleichen abzufragen.
• Hilfedateien oder Anmerkungen neben dem Eingabefeld, sind geeignet, beim
Benutzer entstehende Fragen zu beantworten oder Unsicherheit abzubauen.
Schlusswort
Oftmals genügt es, einige wenige Sicherheitsregeln konsequent umzusetzen,
um die Anfälligkeit auf Attacken massiv einzudämmen und auch gegen zukünftige
Sicherheitslücken seitens PHP gesichert zu sein.