Geklaute Sitzung
Bei „Container Managed Security“ sollen Java Application Server die Authentifizierungsdaten für Webanwendungen verwalten. Sind sie aber nicht richtig konfiguriert, kann sich ein Angreifer eine Sitzung erschleichen und unberechtigterweise Zugriff erhalten.
- Thomas Götz
- Olaf Flebbe
Vertraulichkeit und Integrität der Daten spielen bei Unternehmensanwendungen eine wichtige Rolle. Um diese Anforderungen in die Praxis umzusetzen, bedarf es sicherer Authentifizierungsverfahren. Für besonders schützenswerte Anwendungen kommt dabei häufig eine Zwei-Faktor-Authentifizierung zum Einsatz, beispielsweise mit Hardware-Token. Die Investitionen in solche Token sind in der Regel erheblich, und der erwartete Sicherheitsgewinn muss deshalb in einem angemessenen Verhältnis zu den Kosten stehen. Angriffe wie der vorgestellte, die sich auch gegen solche besonders abgesicherten Anwendungen richten, verdienen daher besonderes Augenmerk.
Webanwendungen nutzen neben den Authentifizierungsverfahren in HTTP wie Basic Authentication, Digest MD5 oder SPNEGO mit Kerberos oder NTLM oftmals sessionbasierte Authentifizierung mit HTML-Formularen. Damit sich die verschiedenen HTTP-Requests einer bestimmten Session zuordnen lassen, kommen ĂĽblicherweise HTTP-Cookies zum Einsatz. Die Webanwendung setzt diese Cookies zu Beginn einer Session, und der Browser liefert sie bei allen nachfolgenden Requests an den Webserver zurĂĽck.
Diese Cookies sind zumeist anwendungsspezifisch gesetzt und so definiert, dass sie nur für diese Anwendung an den Anwendungsserver gesendet werden. Der Verlust eines solchen Cookie bedeutet in aller Regel, dass ein Angreifer mit den Berechtigungen des Nutzers auf die Anwendung zugreifen kann. Verwundbarkeiten anderer Server innerhalb einer Domain, zum Beispiel durch Cross-Site Scripting (XSS), gefährden damit die Anwendung nicht unmittelbar.
Meine Session, deine Session
Neben dem weitläufig bekannten XSS-Angriffsszenario gibt es mit Session Fixation eine weitere potenzielle Verwundbarkeit von Webanwendungen. Bei diesem Angriff schiebt der Angreifer einem Anwender eine nichtauthentifizierte Session unter, die dieser authentifizieren soll. Da der Angreifer die Session-ID kennt, kann er nun mit den Berechtigungen des Anwenders auf die Applikation zugreifen. Voraussetzung dafür ist, dass das Session-Cookie nach erfolgreicher Authentifizierung nicht verworfen wird (siehe Kasten) – was viele Web-Frameworks leider standardmäßig tun.
So funktioniert ein Session-Fixation-Angriff
- Zunächst besorgt sich der Angreifer eine Session-ID, indem er auf die Anwendung zugreift. In aller Regel wird beim ersten HTTP-Request ein Session-ID-Cookie gesetzt.
- Anschließend sucht er eine weitere, für Cross-Site-Scripting-Angriffe (XSS) verwundbare Anwendung innerhalb der gleichen DNS-Domäne.
- Er konstruiert eine URL, mit deren Hilfe es möglich ist, die Session-ID der ursprünglichen Anwendung für die gesamte Domain zu setzen.
- Der Angreifer bringt das Opfer dazu, diese URL aufzurufen.
- Das Opfer authentifiziert sich gegenĂĽber der Anwendung.
- Der Angreifer kann nun mit den Rechten des Opfers auf die Anwendung zugreifen.
Java Servlet Container und Java Application Server bieten als Option die sogenannte „Container Managed Security“ an. Dabei kommt dem Server die Aufgabe zu, die im Zusammenhang mit einer Session hinterlegten Authentifizierungsinformation eines Anwenders zu übernehmen. Die Webanwendung verwendet die Informationen aus dem Session Context, um die Identität des Benutzers zu bestimmen.
Leider erneuern viele populäre Servlet-Container wie Tomcat, JBoss und JOnAS (Java Open Application Server) den Session Context und damit das zugehörige HTTP-Cookie nach erfolgreicher Authentifizierung mit Container Managed Security nicht. Um die Session-ID zu ändern, müssten sie nach erfolgreicher Authentifizierung eine neue Session anlegen und die vorherigen Informationen in die neue übernehmen. Die vorherige Session ist anschließend zu verwerfen.
Im Tomcat und darauf aufbauenden Servlet-Containern kann man das durch einen sogenannten Valve erreichen, den man in der server.xml konfiguriert. Damit kann der Administrator Code hinzufügen, der zusätzlich zur Authentifizierung des Benutzers die Session und damit die Session-ID erneuern kann (Listing 1).
Listing
....
public class SessionFixationProtectionValve extends ValveBase {
....
public void invoke(Request request, Response response) throws IOException, ServletException {
....
// Session bestimmen
Session session = request.getSessionInternal( false);
if (session != null) {
// Standard-URI fĂĽr Container Managed Security
if (request.getDecodedRequestURI().endsWith("/j_security_check")) {
// schon eine Session vorhanden
HttpSession httpSession = request.getSession( false);
if (httpSession != null) {
HashMap<String, Object> attributes = new HashMap<String,Object>();
// alle Attribute kopieren
Enumeration<String> enames = httpSession.getAttributeNames();
while (enames.hasMoreElements()) {
String name = enames.nextElement();
if (!name.equals("JSESSIONID"))
attributes.put(name, httpSession.getAttribute( name));
}
// alle Notizen kopieren
HashMap<String, Object> notes = new HashMap<String,Object>();
Iterator<String> nameit = session.getNoteNames();
while (nameit.hasNext()) {
String name = nameit.next();
notes.put( name, session.getNote( name));
}
// Session ungĂĽltig machen
httpSession.invalidate();
session.expire();
session.recycle();
// neue Session anlegen
httpSession = request.getSession( true);
// Attribute und Notizen zurĂĽckkopieren
for (Map.Entry<String,Object> et : attributes.entrySet()) {
httpSession.setAttribute( et.getKey(), et.getValue());
}
session = request.getSessionInternal( true);
for (Map.Entry<String, Object> et : notes.entrySet()) {
session.setNote( et.getKey(), et.getValue());
}
}
}
}
getNext().invoke(request, response);
}
...
}
Nachbesserungen „per Hand“
Der JBoss-Applikations-Server weist eine zusätzliche störende Eigenschaft auf. Durch den gerade beschriebenen Ansatz kann man zwar bewirken, dass er eine neue Session generiert, er verwendet jedoch weiterhin dieselbe Session-ID, weshalb der Angriff noch immer möglich ist.
Um JBoss so zu konfigurieren, dass er wirklich eine neue Session-ID vergibt, muss der Systemverantwortliche in server.xml die Standardeinstellung für emptySessionPath auf „false“ setzen. Das kann jedoch Probleme bei bestimmten Applikationen verursachen. Bei Tomcat und JOnAS ist es die Standardkonfiguration.
Eine andere Möglichkeit der Authentifzierung bei Java-Applikationen ist die sogenannte Client-Side Security. Die Applikation selbst übernimmt die Authentifizierung. Ein bekanntes Framework zur Implementierung ist zum Beispiel das Spring Security Framework, das unter anderem vor Session-Fixation-Angriffen schützt. Leider läuft auch dieser Schutz bei JBoss ins Leere, aus dem bereits genannten Grund, dass dieser stets dieselbe Session-ID generiert. Die oben beschriebene Änderung in der server.xml ist hier zwingend erforderlich.
Verwundbarkeit einfach aufzuspĂĽren
Um zu prüfen, ob eine Anwendung durch Session-Fixation verwundbar ist, kann man beispielsweise das Firefox-Add-on „Live HTTP Headers“ einsetzen. Beim ersten Zugriff auf die Anwendung setzt diese in der Regel das JSESSIONID-Cookie. Sollte nach erfolgreicher Anmeldung eine andere JSESSIONID gesetzt werden, ist die Anwendung vor Session Fixation geschützt. Neben dem Ändern der Session-ID gibt es jedoch weitere Techniken, die die Anwendung schützen. So kann der Entwickler nach erfolgreicher Authentifizierung ein zweites Cookie setzen, das bei jedem Request geprüft wird. Ein gewisser Schutz lässt sich auch herstellen, indem eine Session einer bestimmten IP-Adresse zugeordnet wird.
Fazit: Webanwendungs-Entwickler und Administratoren von Webanwendungen sollten sich auch bei Container Managed Security nicht auf die Servlet Container oder Applikationsserver verlassen. Selbst wenn die Entwickler Session-Fixation-Angriffe berücksichtigt haben, kann eine Anwendung durch die Konfiguration des Containers verwundbar sein. Gerade bei Session Fixation lässt sich die Verwundbarkeit aber sehr einfach überprüfen.
Thomas Götz
ist Security Solution Architect bei der TĂĽbinger science+computing ag.
Dr. Olaf Flebbe
ist Chief Software Architect bei der TĂĽbinger science+computing ag.
Dieser Artikel gehört zur dreiteiligen Titelstrecke der iX 2/2010 zum Thema "Gefahr aus dem Web". Das Heft kann online erworben werden und wird in Deutschland ohne Versandkosten zugeschickt. (ur)