Sichere Java-Webanwendungen, Teil 2: Cross-Site Request Forgery

Seite 3: Formularschutz und Tools

Inhaltsverzeichnis

Eigentlich fallen Log-in- und Log-out-Formulare nicht in die Kategorie kritischer (zustandsverändernder) Formulare. Die Notwendigkeit, sie vor CSRF zu schützen, wird daher häufig übersehen. Log-in-Formulare vor CSRF abzuschirmen ist nötig, damit sich Benutzer nicht mit ihnen untergeschobenen Benutzerdaten anmelden können. Ein Angreifer könnte sonst einen Anwender heimlich mit seinen für den Angriff angelegten Benutzerdaten anmelden und dessen ausgeführte Operationen exakt nachvollziehen. Je nach Webanwendung gibt der Benutzer bei der Interaktion mit der Webanwendung unterschiedliche sensible Informationen preis – etwa Kreditkarteninformationen für eine Bestellung – die der Angreifer anschließend einsehen kann.

Log-out-Formulare benötigen hingegen Schutz, damit Benutzer nicht ungewollt abgemeldet und wie im Abschnitt zuvor beschrieben mit den Benutzerdaten des Angreifers wieder angemeldet werden können. Denkbar ist zudem, den Benutzer nach der Abmeldung sofort auf eine vom Angreifer manipulierte Log-in-Seite umzuleiten. Die dort eingegebenen Benutzerdaten werden vom Angreifer abgefangen und später von ihm wiederverwendet. Daher muss auch ein Log-out-Formular einen POST-Request auslösen und nicht nur einen simplen GET-Request per Log-out-Link.

Wie jede clientseitige Information ist das Anti-CSRF-Token prinzipiell per Cross-Site Scripting (XSS) auslesbar. Eine derart verwundbare Webanwendung lässt sich daher nicht zuverlässig vor Cross-Site Request Forgery schützen. Ein Angreifer könnte schließlich zunächst den Wert des Anti-CSRF-Token aus dem Formular auslesen und ihn im eigenen Request verwenden. Für einen zuverlässigen Schutz vor CSRF ist es daher unabdingbar, dass die Webanwendung zunächst vor XSS geschützt ist.

Da sich die wichtigste Maßnahme gegen CSRF – das Anti-CSRF-Token – relativ leicht in Frameworks integrieren lässt, ist sie immer häufiger in deren Code enthalten. JavaServer Faces (JSF) etwa schützen schon geraume Zeit vor CSRF und mit der zuletzt veröffentlichten Version 2.2 gab es erneute Verbesserungen. Die Funktion des Anti-CSRF-Tokens übernimmt dabei das javax.faces.ViewState-Token, das ohne Zutun des Entwicklers in jedem Formular enthalten ist und sich nach jedem Request ändert (im folgenden Screenshot wurde das versteckte Token per Browser-Add-on sichtbar gemacht):

Automatisch von JSF generiertes Token zum Schutz vor CSRF-Angriffen (Abb. 1).

Seit Version 3.2 enthält Spring Security ebenfalls einen einfach zu verwendenden CSRF-Schutz. Auch hier ändert sich der Token-Wert mit jedem Request. Der CSRF-Schutz ist beim Einsatz einer Java-Konfiguration automatisch immer aktiv. Lediglich bei Verwendung der XML-Konfiguration ist er zumindest derzeit noch explizit durch das Hinzufügen des csrf-Elements zu zu aktivieren:

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<!-- ... -->
<http>
<!-- ... -->
<csrf />
</http>
</beans>

Des Weiteren müssen Entwickler die gewünschten Formulare meist durch ein Anti-CSRF-Token erweitern (bei Verwendung des Spring MVC beispielsweise wird das Token dem Formular automatisch hinzugefügt):

<form name="orderForm" action="OrderServlet" method="POST">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<label for="product" title="Product">Product</label>
<input type="text" id="product" name="product" />
<!-- ... -->
<input type="submit" value="Order" />
</form>

CSRF-Schutzmaßnahmen sollten Entwickler unabhängig vom gewählten Framework grundsätzlich immer im Browser testen. Dazu fälscht man das Anti-CSRF-Token und prüft die Reaktion des Backends. Ein empfehlenswertes (wenn auch nicht mehr weiterentwickeltes) und einfach zu verwendendes Firefox-Browser-Add-on dafür ist Groundspeed, mit dem man selbst versteckte Formularwerte schnell manipulieren kann. Deutlich umfangreichere Tools wie der Intercepting-Proxy OWASP ZAP ermöglichen ebenfalls die Manipulation des Tokens nach dem Abschicken des Requests.

Das Überprüfen des Backends ist die zweite wichtige Maßnahme. Hierbei werden die Operationen direkt und ohne den Umweg über den Browser aufgerufen. Bei fehlendem Token ist der Request unmittelbar abzuweisen.