Cross-Site-Scripting
Als Cross-Site-Scripting auch XSS genannt, bezeichnet man eine Angriffsart bei der Sicherheitslücken ausgenutzt werden, um bei dem Client schadhaften Code auszuführen. XSS Angriffe sind überall da möglich, wo Benutzereingaben ohne weitere Prüfung an einen Browser zur Weiterverarbeitung gesendet werden. Da sich XSS Angriffe, wie schon erwähnt, an die Benutzer einer Webanwendung richten, kommen Clientseitige Scriptsprachen wie Javascript zum Einsatz. Durch diese könne sensible Daten wie Benutzernamen und Passwörter, z.B bei Login Formularen, ausspioniert werden und ein Dritter kann sich somit unerlaubten Zugang zum Account verschaffen.Wie vermeidet man nun XSS Angriffe?
Um solche Angriffe zu vermeiden, sollten alle Benutzereingaben geprüft, HTML-Tags und Sonderzeichen entfernt bzw. maskiert werden.Um die Benutzereingaben auf gültige Zeichen zu prüfen bieten, sich so genannte Whitelist Prüfungen bzw. reguläre Ausdrücke an. Der Vor- und Zuname einer Person enthält in der Regel nur Groß- und Kleinbuchstaben und keine Zahlen oder Sonderzeichen. Eine E-Mail Adresse oder Internetadresse hat eine bestimmte Syntax. Postleitzahlen haben eine bestimmte Anzahl von Zahlen und bestehen nur aus Ziffern.
Mehr Informationen zu regulären Ausdrücken findet Ihr hier.....
Bei Benutzereingaben wie Kommentaren, Forenbeiträgen oder Gästebucheinträgen ist die Überprüfung der Eingaben nicht ganz so einfach. Hier muss man zwangsläufig Satzzeichen, Sonderzeichen, Buchstaben und Zahlen zulassen. Wenn man seinen Besuchern noch die Möglichkeit bieten möchten die Beiträge etc. individuell zu gestalten, so muss man HTML-Tags zulassen. Hier kann man auf die PHP-Funktionen strip_tags() und htmlentities() zurückgreifen.
Wie strip_tags() funktioniert und wie man es einsetzt, beschreibe ich in Angriffe durch das Manipulieren von Parametern.
Die Funktion htmlentities() wandelt alle HTML-Sonderzeichen in Entity-Codes um. So wird aus dem folgenden String:
In dem Beispiel wird die Funktion htmlentities() um die Konstante ENT_QUOTES erweitert, denn so lassen sich auch einfache und doppelte Anführungszeichen in den entsprechenden Entity-Code umwandeln.
Beispiel:
$string = ′<script languag="javascript">alert('XSS');</script>′
$string_ent = htmlentities($string,ENT_QUOTES);
?>
Möchte man seinen Usern trotzdem die Freiheit bieten Texte zu formatieren, wäre eine BBCode Klasse zu empfehlen.
Auch legitime Funktionen der Internet Browser können ausgenutzt werden um an sensible Daten von Besuchern ran zukommen.
Benutzername/Passwort Kombinationen können über den Browser im Password Safe hinterlegt werden. Wenn man nun den Password Safe benutzt, muss man sich beim nächsten Login nicht mehr die Login Daten merken, denn sie werden automatisch in die entsprechenden Formularfelder eingefügt. Dabei wird das Passwort sowohl im Passwort Safe, wie auch beim Einfügen in das Formularfeld in Klartext dargestellt, was eine nicht unerhebliche Gefahr darstellt. Auch wenn das Passwort als *** im Formularfeld dargestellt wird, kann man dies mittels DOM (Document Object Modell) auslesen.
Um automatische Formularvervollständigungen zu vermeiden, kann man dynamische Formularfelder verwenden.
Als erstes generiert man mit Hilfe der PHP Funktionen md5() und rand() einen zufälligen Schlüssel.
Beispiel:
$schluessel = md5(rand(0,99999));
?>
Beispiel:
<input type="text" name="benutzername[<?php echo $schluessel ?>]">
<input type="password" name="passwort[<?php echo $schluessel ?>]">
<input type="hidden" name="schluessel" value="<?php echo $schlussel ?>">
<input type="submit">
</form>
Möchten man nun für die Weiterverarbeitung auf die Benutzerdaten zugreifen, funktioniert das nach dem Absenden des Formulars wie folgt:
Beispiel:
$schluessel = $_POST['schluessel'];
$benutzername = $_POST['benutzername'][$Schluessel];
$passwort = $_POST['passwort'][$schluessel];
?>
Header Variablen enthalten Informationen über den Server und dessen Ausführungsumgebung. Auch wenn Benutzer keinen direkten Zugriff auf die Variablen haben, so können diese mit Browser Plugins manipuliert werden. Sprich, auch aus dieser Variable können Parameter mit bösen Absichten übergeben werden, aus diesen Grund sollte man auch Header Variablen stets wie Benutzereingaben behandeln.
Bei der Entgegennahme von Formularfeldern, sollte man auf die Super Globale Variable $_REQUEST verzichten, da diese alle Werte aus den Request Methoden $_POST und $_GET beinhaltet. So kann also nie sichergestellt werden, wo genau die Werte herkommen die mit $_REQUEST abgerufen werden.
So wäre es z. B. Möglich, ein Script, dessen Formulardaten mit $_REQUEST entgegengenommen wurden, über die URL Parameter zu übergeben und auszuführen. Was wiederum vom Entwickler eventuell nicht so gewollt ist.
Wird ein Formular abgeschickt, empfiehlt es sich zu überprüfen ob dies auch vom Anwender so gewollt ist, damit der Angreifer keine Aktionen im Namen der Benutzer ausführen kann, ohne das die Benutzer etwas davon mitbekommen.
Beispiel:
session_start();
function check_form_token($form_token){
if(!isset($_SESSION[$form_token.'_token')){
return false;
}
if(isset($_POST['token'])){
return false;
}
if($_SESSION[$form.'_token'] !== $_POST['token']){
return false;
}
return true;
}
function token($form){
$token = md5(uniqid(microtime(),true));
$_SESSION[$form.'_token'] = $token;
return $token;
}
Beispiel:
$token = token('form');
?>
<from>
<input type="hidden" name="token" value="<?php echo $token ?>">
</form>
Beispiel:
if(check_form_token('form')){
//Formular verarbeiten
}else{
//Verarbeitung abbrechen
}
?>