Sicherheit:
Durch Eingabe von Code in die Adresszeile oder in ein Formularfeld, welches zu einer Abfrage, einer Ausgabe im Browser oder einem Datenbankeintrag führt, oder durch einen Datei upload, lässt sich schädlicher Code einschmuggeln und ausführen. Folgende Sicherheitshinweise gilt es zu beachten.
Hacker
Es trifft immer die Unterentwickelten und Schwachen.
Es gibt Hacker, die üben sich an Banken und Regierungen. Hey, nichts gegen Robin Hood!
Und es gibt auch immer wieder einen, der löscht mit vorliebe den selbstgebastelten Blog
und unbedeutende Wikis, ersetzt hier die index-Datei und präsentiert sich dann ganz stolz.
Wichtige Stichworte zum Thema Sicherheit sind:
>> Cross-Side Scripting
und >> SQL-Injection!
Benutzer-Eingaben Prüfen
Allgemeine Sicherheitsregeln:
- Es darf keiner übermittelten Variablen, keiner empfangenen Zeichenkette vertraut werden.
- Alle Variablen im Vornherein initialisieren, um sie überprüfen zu können
- Wisse woher die Variablen kommen: nur $_POST verwenden (statt $_GET oder gar $_REQUEST)
- Limitiere, zähle und vergleiche die zu erwartende Anzahl Worte oder Zeichen.
- Kontrolliere nicht nur auf böse Zeichen, sondern vergleiche den übermittelten Wert aus 'hidden-fields' oder 'optionen', 'checkboxen' und 'dropdown-menüs' mit dem erwarteten Wert.
- Validiere den Input mit Regülären Ausdrücken durch Funktionen oder Filter
- Fehlermeldungen im produktiven system ganz abschalten: error_reporting(0);
Keine Benutzer-Dateien speichern
Durch Bild- oder Datei- Uploads können Scripts eingeschleust und zur Ausführung gebracht werden. Diese Scripts ermöglichen den Zugriff auf die Site. Ich rate dem Lehrling ab, jemandem die Möglichkeit zum Upload einer Datei anzubieten.
PHP Code
Umwandeln von Benutzereingaben
-
strip_tags()
strip_tags() - löscht alle HTML und PHP Tags -
htmlspecialchars()
htmlspecialchars($var,ENT_QUOTES) - Konvertiert die HTML Spezialcharakter < in <, > in >, & in & und " in " um. Mit dem zweiten Parameter ENT_QUOTES auch noch ' in '.
quote_style gibt zusätzlich das Verfahren gegenüber Anführungszeichen an:
ENT_COMPAT konvertiert nur doppelte Anführungszeichen und lässt einfache Anführungszeichen unverändert (Grundeinstellung wenn nichts.
ENT_QUOTES konvertiert sowohl doppelte als auch einfache Anführungszeichen.
ENT_NOQUOTES lässt doppelte und einfache Anführungszeichen unverändert.
htmlspecialchars_decode() wandelt alles wieder zurück. -
htmlentities()
htmlentities(string, quote_style) - Wandelt zusäzlich auch die Umlaute ü, ö und ä um.
html_entity_decode() wandelt alles wieder zurück. -
addslashes()
addslashes(), quotemeta() oder addcslashes(), setzen einen Backslash vor Anführungszeichen (einfache und doppelte)
stripslashes() löscht die backslashes, die eine aktivierte magic_quotes Einstellung beim Übertragen von Formulardaten erzeugt hat. -
preg_replace()
preg_replace($suchen,$ersetzen,$imstring) ersetzt in Strings und Arrays reguläre Ausdrücke.
Auf diesen String angewendet erzeugen obige Funktionen folgenden Output:
$myInput="<b>Ich bin fett</b> und ich hab 'n Apostrophe ähhh und \"ich bin angeführt\"."
Ich bin fett und ich hab 'n Apostrophe ähhh und "ich bin angeführt".
htmlspecialchars:
<b>Ich bin fett</b> und ich hab 'n Apostrophe &auml;hhh und "ich bin angef&uuml;hrt".
htmlspecialchars mit ENT_QUOTES:
<b>Ich bin fett</b> und ich hab 'n Apostrophe &auml;hhh und "ich bin angef&uuml;hrt".
htmlentities mit ENT_QUOTES:
<b>Ich bin fett</b> und ich hab 'n Apostrophe &auml;hhh und "ich bin angef&uuml;hrt".
addslashes:
<b>Ich bin fett</b> und ich hab \'n Apostrophe ähhh und \"ich bin angeführt\".
preg_replace('/(<|>|&|'|")/','*',$myInput):
*b*Ich bin fett*/b* und ich hab *n Apostrophe *auml;hhh und *ich bin angef*uuml;hrt*.
Typen erkennen von Zahlen / umwandeln in Zahlen
-
is_string()
is_string(), ist der Input ein String? (gibt 1/TRUE zurück wenn's stimmt, sonst 0/FALSE - was nichts ist) -
is_numeric()
is_numeric(), ist der Input ein numerischer String? (stimmt gibt 1 zurück ...) -
is_int()
is_int(), ist der Input eine Zahl? (stimmt gibt 1 zurück ...) -
ctype_digit()
ctype_digit(), prüft einen String auf Ziffern und anerkennt vorangestellte Nullen als solche. (stimmt gibt 1 zurück ...) -
(int)$benutzereingabe; oder intval($benutzereingabe);
mit (int)$benutzereingabe; oder auch mit intval($benutzereingabe); erfolgt Umwandlung in integer. (Erfolg gibt die gewandelte Zahl zurück!) -
settype($Variable, Typ);
Mit settype($Variable, 'int'); erfolgt Umwandlung in integer. (Erfolg gibt 1 zurück!)
Auf diese Strings angewendet erzeugen obige Funktionen folgenden Output:
007666
007is666
1
1
is_numeric:
1
is_int:
ctype_digit:
1
intval:
7666
7
settype int:
1
1
Verschlüsselung
Die Umwandlungen durch folgende Funktionen können genutzt werden um eindeutige Sessions zu generieren. Auch zur Übermittlung eines Wertes, der dann beim Einlesen durch Vergleich geprüft werden soll, leisten diese Funktionen ihren Dienst. Umkehrar ist dies jedoch nicht, denn es geht eher um hier eine Quersumme, denn um eine Verschlüsselung mit einem Schlüssel!
md5()
md5($myInput): 481af042c1e012b838ef9692b8c6e6c3
crc32()
crc32($myInput): 1173878966
Verstecken und Verbieten
.htaccess
Zugangsdaten (z.B. in .inc Dateien abgelegt), sollen nicht in ungeschützten Verzeichnissen liegen! Errät man die Namen, kann die Datei einfach im Browser aufgerufen werden. Durch .htaccess-Dateien in speziel benannten Ordnern, kann der Zugriff auf diese Dateien von Aussen her verboten werden, der Zugriff von innen her (für die Scripte) bleibt dabei erhalten.
<FilesMatch "\.inc$"> Deny from all </FilesMatch>
Zugriff auf mehrere Datei-Typen verbieten:
<FilesMatch "\.(inc|dat)$"> Deny from all </FilesMatch>
Verstecken oder Zugriffverweigerung wäre eigentlich unnötig, würden die Include-Dateien etwa so heissen: inc_wasichmach.php (statt Endung .inc), den PHP-Dateien werden geparst und somit leer dargestellt. Mehr zu .ht-Dateien (im Teil 'Andere' im Kapitel 'Apache Server'). Mehr zu Passwortschutz durch .htaccess (im Teil 'Andere' im Kapitel 'Apache Server').
Achtung, die Angabe der zu schützenden Dateien in der Datei robots.txt (bitte nicht indexieren) ist natürlich ein Humbug!
Siehe: Server
SQL Code
- Stelle nie als Superuser oder Owner einer Datenbank eine Verbindung zur Datenbank her.
Verwende immer speziell angelegte Benutzer mit sehr limitierten Rechten! - Protokolliere die Vorgänge, welche zu einer Veränderung der Datenbank führen
- Mache Backups deiner DB z.B. mit 'MySQLDumper' Freeware (http://mysqldumper.de/)
- Nutze Funktionen (vor Einträgen in Datenbanken): mysql_real_escape_string() / >> mysql_real_escape_string()
- Verhindere gezielt das Löschen ganzer Tabellen oder mehrer Datensätze. Suche in Usereingaben (Querrystring, GET, POST, REQUEST) nach Injections wie
; DROP TABLE tabellenname;--'
, die beiden Bindestriche sorgen dafür, dass das ' als Kommentar ignoriert wird, so wird durch den angehängten Befehl nicht einmal eine Fehlermeldung erzeugt.
mysql_real_escape_string
<?php // Anstatt $abfrage = "SELECT spalte1 FROM tabelle WHERE spalte2 = '".$_POST['spalte2Wert']."'"; $query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); // sollte Folgendes verwendet werden: $abfrage = "SELECT spalte1 FROM tabelle WHERE spalte2 = '".mysql_real_escape_string($_POST['spalte2Wert'])."'"; $query = mysql_query($abfrage) or exit; ?>
HTML/JavaScript Code
htmlentities()
PHP bietet auch Schutz vor Javascripts:
<?php $boesercode = "<script>alert('XSS');</script>"; echo "Sie haben ".htmlentities($boesercode,ENT_QUOTES)." eingegeben"; ?>
Sie haben <script>alert('XSS');</script> eingegeben