10 Mythen zum Thema Web Security
Zum Thema Web Security gibt es viele Behauptungen, Vorurteile und falsche Einschätzungen.
Dadurch werden falsche Informationen verbreitet und unzureichende Schutzmaßnahmen angewendet. In diesem Artikel werden 10 beliebte Mythen zum Thema Web Security aufgedeckt.
Zu einigen dieser Mythen gibt es auch praktische Beispiele, die demonstrieren sollen, wie Angreifer unzureichende Schutzmaßnahmen umgehen können.
Sind statische Webseiten sicher? Sind client-seitige Sicherheitslücken wie Cross-Site Scripting (XSS) wirklich harmlos?
Das und einiges mehr wird in diesem Artikel aufgedeckt.
- 1. Statische Webseiten sind sicher
Viele meinen statische Webseiten (HTML-Dokumente) sind sicher, weil keine serverseitigen Scriptsprachen wie PHP verwendet werden und somit auch keine Sicherheitslücken entstehen können.
Für die Webseiten ansich mag das stimmen. Allerdings liegen Webseiten immer auf einem Server und dieser kann auch Sicherheitslücken aufweisen. Somit könnten Angreifer Zugriff auf die entsprechenden (HTML-)Dateien erlangen.
Es müssen allerdings nicht zwingend Sicherheitslücken in der Server-Software vorhanden sein. Viele Website-Betreiber nutzen Webhosting-Pakete und keinen eigenen Server. Jedem Kunden wird ein entsprechender Speicherplatz auf dem Server zugewiesen. Auf dem selben Server hosten also noch sehr viele andere Kunden ihre Webseiten – und garantiert nicht nur Statische. Sind dort Sicherheitslücken in Webanwendungen vorhanden, könnten sich Angreifer Zugriff auf dem Server verschaffen. Verschiedene Verzeichnisse haben auf einem Shared Server zwar einen Zugriffsschutz, versierte Angreifer könnten in manchen Fällen mit einigen Tricks aber auch diesen Schutz umgehen und auf beliebige Verzeichnisse zugreifen. Dazu schreibe ich noch einen eigenen Artikel.
- 2. Meine Webseiten sind für Angreifer uninteressant
Nur weil keine sensiblen Daten wie Passwörter, Kundendaten, etc. vorhanden sind, heißt es noch lange nicht, dass Angreifer kein Interesse an Ihren Webseiten haben.
Webseiten können auf verschiedenster Weise manipuliert werden. Werden Dateien zum Download angeboten, könnten diese vertauscht werden, Links könnten so manipuliert werden, dass sie zu infizierten Webseiten führen, Proxy-Server könnten installiert werden, Phishing-Seiten könnten hochgeladen werden, etc.
- 3. HTTP-Authentifizierungen sind sicher
Werden bei HTTP-Authentifizierungen schwache Passwörter (oder Benutzernamen) verwendet, könnten Angreifer diese mittels Brute-Force oder Dictionary-Attacken knacken. Aber selbst wenn sichere Logindaten verwendet werden, bedeutet das nicht, dass dieser Schutz immer sicher ist.
Es gibt zum Beispiel eine Methode mit der Angreifer bestimmte HTTP-Authentifizierungen durch Manipulation der HTTP-Methode umgehen können.
- 4. Cross-Site Scripting (XSS) Sicherheitslücken sind harmlos
Dies ist eines der häufigsten Vorurteile gegen XSS von “selbsternannten Experten”.
Dabei wissen die meisten noch nicht mal genau, was mit XSS alles möglich ist. XSS Sicherheitslücken werden am häufigsten zum Stehlen von Cookie-Informationen ausgenutzt. In Cookies werden oft sensible Informationen übermittelt. Das können verschlüsselte (manchmal sogar auch unverschlüsselte) Logindaten oder Session-ID’s (SIDs) sein mit denen Angreifer die aktuelle Sitzung / Session entführen können (Session Hijacking – dazu werde ich ebenfalls noch einen Artikel schreiben).
Das Stehlen von Cookies ist aber nicht das einzige, was Angreifer mit XSS anstellen können. Angreifer könnten zum Beispiel eine XSS-Shell injizieren und sämtliche Daten des Benutzers abfangen – u. A. werden XSS-Shells auch als temporäre Keylogger genutzt.
Mittels DOM-based XSS kann client-seitiger Code auch lokal mit den Rechten des aktuellen Benutzers ausgeführt werden. Bei alten IE Versionen könnte das sogar zu Remote Execution (und somit zum Zugriff auf dem Rechner) führen.
- 5. Die Funktion »htmlspecialchars« verhindert automatisch XSS
Mit den PHP Funktionen htmlspecialchars() und htmlentities() kann man XSS verhindern. Allerdings können diese Funktionen auch falsch angewendet werden.
Dazu folgendes Beispiel:
<?php if(isset($_POST['textfeld']) && !is_array($_POST['textfeld'])) $textfeld = htmlspecialchars($_POST['textfeld']); else $textfeld = ''; $form = "<form action='' method='post'>\n"; $form .= "<input type='text' name='textfeld' value='$textfeld' size='30' /><br /><br />\n"; $form .= "<input type='submit' name='senden' value='Absenden' />\n"; $form .= "</form>"; echo $form; ?>Wird im Textfeld zum Beispiel normaler JavaScript Code eingegeben und das Formular abgesendet, werden spezielle Zeichen (wie gewollt) in HTML-Code umgewandelt:
value='<script>alert(1);</script>Was auf den ersten Blick gut aussieht, stellt sich bald als potenzielle Sicherheitslücke heraus. Die Funktionen htmlspecialchars() und htmlentities() kodieren zwar Zeichen, die normalerweise XSS verhindern, allerdings wird ein bestimmtes Zeichen standardmäßig nicht kodiert: das einfache Anführungszeichen.
Da hier die Variable »textfeld« (welche die Benutzereingaben enthält) in einfachen Anführungszeichen, anstatt doppelten Anführungszeichen steht, kann aus dem value-Attribut ausgebrochen werden und JavaScript Event-Handler können injiziert werden, womit JavaScript Code bei bestimmten Aktionen ausgeführt werden kann.
Man könnte zum Beispiel folgenden String ins Textfeld injizieren:
' onmouseover='alert(123);Beim Überfahren des Textfelds mit der Maus wird der JavaScript Code ausgeführt. In diesem Beispiel eine harmlose Alert-Box. Wer sich diesen String genau anschaut, wird feststellen, dass dort kein einziges Zeichen vorhanden ist, das die Funktionen htmlspecialchars() und htmlentities() standardmäßig kodieren würden.
Um auch einfache Anführungszeichen zu kodieren, muss der Modus ENT_QUOTES verwendet werden. Dieser wird den Funktionen als Parameter übergeben.
$textfeld = htmlspecialchars($_POST['textfeld'], ENT_QUOTES); - 6. Die Funktion »mysql_real_escape_string« verhindert automatisch SQL Injection
- 7. »magic_quotes_gpc« verhindert automatisch SQL Injection
In vielen Fällen können Angreifer magic_quotes_gpc umgehen – zum Beispiel mit der SQL Funktion CHAR() oder mit Hexadezimal-Werten.
magic_quotes_gpc wird in PHP 6.0.0 entfernt.
- 8. DDoS Protection Scripte verhindern DDoS-Attacken
Kein Script der Welt bietet einen effizienten Schutz gegen DDoS. Gegenmaßnahmen sollten auf tieferer Ebene stattfinden – zum Beispiel beim Grenzrouter des Providers oder wenn nötig auf Server-Ebene. Einen 100%igen DDoS-Schutz gibt es jedoch nicht.
- 9. Der X-Forwared-For HTTP-Header enthält immer die echte IP Adresse
Natürlich nicht. Bei anonymen Proxies kann die echte IP Adresse nicht so einfach ausgelesen werden. Erstrecht nicht, wenn eine Proxy-Chain verwendet wird.
- 10. Validiere $_GET, $_POST, $_COOKIE und dein PHP Script ist sicher
Dies ist ein häufiger Fehler von PHP Programmierern. Benutzereingaben bzw. Daten von Aussen könnten beispielsweise auch im superglobalen Array $_SERVER an die Webanwendung übermittelt werden. $_SERVER['HTTP_USER_AGENT'] enthält zum Beispiel den User-Agent String, der im Browser beliebig verändert werden kann. In einem anderen Artikel habe ich einige davon aufgelistet.
Die PHP Funktion mysql_real_escape_string() verhindert SQL Injection, wenn Benutzereingaben, die in einer SQL-Anweisung verwendet werden, sich innerhalb eines Strings befinden – also mit Anführungszeichen umschlossen sind.
Ist dies nicht der Fall, ist SQL Injection möglich, da die Funktion mysql_real_escape_string() – wie der Name schon sagt – nur bestimmte Zeichen innerhalb eines Strings maskiert.
Dazu wieder ein (vereinfachtes) Beispiel:
<?php
// ...
if(isset($_GET['id']) && !is_array($_GET['id']))
$id = mysql_real_escape_string($_GET['id']);
else
$id = 1;
$sql = "SELECT ID FROM Users WHERE ID=$id";
mysql_query($sql) or die(mysql_error());
?>
Die Variable »id« befindet sich nicht in einem String. Das ist auch nicht nötig, da sie eine ID enthalten soll, die numerisch ist. SQL Injection wär hier problemlos möglich. Würde sich die Variable in einem String befinden, wär SQL Injection nicht möglich. In einigen Fällen kann aber auch mysql_real_escape_string() umgangen werden.
Um SQL Injection in diesem Beispiel zu verhindern, sollte man den Wert der Variable in einen numerischen Datentyp konvertieren. Dazu kann die PHP Funktion intval() verwendet werden oder man nutzt das Type Casting.
$id = intval($_GET['id']);
$id = (int)$_GET['id'];
