10.01.2022 von Joscha Cepok

Der weit verbreitete Web Server Apache Tomcat ist in der momentan aktuellsten Version 9.0.56 anfällig für Session Hijacking Attacken. Eine standardmäßig eingeschaltete Log-Funktion loggt unter gewissen Umständen den vollständigen Cookie-Inhalt des Clients inklusive potentiell sensibler Cookie-Inhalte, wie JSON Web Tokens. Cloud-Architektur und Microservices begünstigen dabei die Schwere des Problems. Der folgende Artikel zeigt auf, unter welchen Umständen das Problem auftritt und wie dieses gepatcht wird.

Logging durch Libs & Frameworks

Logs begleiten Entwickler:innen durch den Alltag und unterstützen dabei, Prozesse, Fehler und Bugs nachzuvollziehen. Was geloggt werden darf und was nicht, ist durch die DSGVO (GDPR) festgelegt. Vor allem personenbezogene Daten dürfen nicht direkt, sondern nur über Referenzen erfasst werden. Für das Logging selbst werden Bibliotheken wie Log4J genutzt, die seit dem CVE im Dezember 2021 große Aufmerksamkeit bekommen hat. Es gibt jedoch zahlreiche Bibliotheken und Frameworks, die vor allem im Fehlerfall Daten loggen. Dieser Beitrag betrachtet den Apache Tomcat Webserver genauer und erklärt, wie dieser eventuell dazu führen kann, dass sensible Daten einfach zugänglich erfasst werden.

Der Apache Tomcat Webserver ist, wie der Name schon sagt, ein Server, der vor allem zur HTTP(S) Kommunikation genutzt wird. Clientseitig werden Daten verpackt, serverseitig entpackt. Die Kommunikation ist verschlüsselt, ein Datenverlust im Netz ist entsprechend unwahrscheinlich. Auf dem Server werden dann die Daten entpackt und konvertiert, dabei kann es zu Fehlern kommen, wenn der Client nicht alles so verpackt hat, wie der Server dies erwartet. In diesem Fall geht es um den Cookie Header. Dieser kann sensible Informationen enthalten. Wie geht man nun damit um, wenn dieser nicht den Erwartungen entspricht und der Cookie Parser ihn nicht vollständig interpretieren kann? In diesem Fall ist im Tomcat folgende Fehlermeldung vorgesehen:

cookie.invalidCookieValue=A cookie header was received that contained an invalid cookie [{0}]. That cookie will be ignored.

Der Platzhalter {0}, durch welchen nachvollziehbar ist, warum das Parsen fehlschlug, bedarf etwas mehr Aufmerksamkeit.

Sessions übernehmen

Das Problem ist, dass der Cookie Parser bei Fehlern zu viele Informationen preisgibt. Durch {0} werden alle Cookies, die in dem Header enthalten sind, als Klartext geloggt. Ein invalider Wert führt dazu, dass alle Cookies geloggt werden. Das ist problematisch, wenn unter den Cookies sensible Informationen enthalten sind, wie z.B. ein JSON Web Token, das genutzt wird, um eine authentifizierte Person zu identifizieren. Dieser Inhalt ist eine sensible Information, auf die nur die berechtigte Person Zugriff haben sollte. Sofern in diesem Token abseits des best Practice keine Attribute enthalten sind, welche sicherstellen, dass das Cookie nur auf dem Client verwendbar ist, haben alle Personen, die hier Zugriff haben, ein leichtes Spiel die Session zu übernehmen (hijacken). Dafür ist nicht viel mehr notwendig als das Cookie manuell in der Entwicklerkonsole entsprechend im Client unter der korrekten Domain, Pfad und mit den entsprechenden Flags zu hinterlegen. Wie funktioniert das? Dafür betrachten wir das JSON Web Token, welches normalerweise folgendermaßen aussieht, genauer:

eyJhbGciOiJSUzUxMiJ9.eyJpZCI6Im15UmVmZXJlbmNlIiwidmFsaWRVbnRpbCI6IjIwMjEtMDEtMTEgMTM6MzciLCJncm91cHMiOiJkZXYsYWRtaW4sc3VwcG9ydCx2aWV3T25seSJ9.jCurOHz-RwdSU6FuqxuhXgFQ6RlZzOjLOE2QQ9-eD_LWAlTPnoEY9LgoCSY8m65AXY2Ln12Nr3NPtIQmSDqGopESp9eO9MSC--SWWJNFWTd-lhyuyUkNWukJwybWWJ7gHRsEfdgVxet_8KmTQRij0VqHkQxHEmY-kaDQpBzHgbfJr3Z6quQ5hCaxLKGUKrcOIUBZGq4I3EM7GVuzaUm_JF5tKTBSe8pgVVHbvIF4IXBxFXLbPDfevjSrJV0Ao1psTp8Wr5MeqnVHBp5PPKn7CiAtJ_yPec5IfBlNb4WBshO_oah2ywcrqxyGSr2Jwsmsrw3q5kTU87Ooo7AKgAajJw

Der Aufbau ist folgender: Codierung.Inhalt.Signatur. Hierbei handelt es sich nur um eine codierte und nicht verschlüsselte Form. Dieses Token kann z.B. auf jwt.io decodiert werden, wodurch der Inhalt sichtbar wird. Die Signatur stellt sicher, dass das Token nicht manipuliert wurde. Der Inhalt sieht decodiert folgendermaßen aus:

{
    "id": "myReference",
    "validUntil": "2021-01-11 13:37",
    "groups": "dev,admin,support,viewOnly"
}

Mit diesen genannten Inhalten wird sichtbar, um welche Person es sich handelt, welche Privilegien sie hat und wie lange die Session gültig ist. An dieser Stelle liegt das Problem: Das Cookie wird im Klartext geloggt und kann somit einfach kopiert werden und ohne Clientbindung von beliebigen Personen verwendet werden.

Im öffentlichen Teil der Plattform kann man damit als Kund:in durch die Plattform navigieren, in den administrativen Backoffice Systemen je nach Privilegien systematisch Aktionen auslösen, um den Betrieb zu sabotieren oder Daten abzugreifen.

Dieses Problem wurde bereits durch Jamie Tanna entdeckt und in seinem Blog dokumentiert. Im direkten Austausch mit ihm wurde deutlich, dass das Problem durch andere Randbedingungen deutlich verschärft und somit erst die Schwere des Problems sichtbar wird.

Bin ich betroffen?

Betroffen sind potenziell alle Systeme, die einen Apache Tomcat Webserver verwenden und clientseitige Cookies zum Identifizieren verwenden.

Damit Session-Informationen abgegriffen werden können, müssen zwei Voraussetzungen erfüllt sein:

In diesem Fall führt das Senden von falsch-formatierten Cookies dazu, dass Cookie-Inhalte im Klartext geloggt werden. Das liegt daran, dass der Cookie Parser den gesamten Inhalt anstatt nur den falsch-formatierten Teil des Cookie-Headers loggt. So führt ein Cookie-Header wie dieser

01.01.1970;cookie1=value1;sensitiveCookie=jsonWebToken

bereits dazu, dass der Tomcat-eigene Cookie Parser den letzten Wert nicht lesen kann, da es kein Schlüssel-Wert Paar ist und damit folgende Logzeile schreibt:

A cookie header was received that contained an invalid cookie [01.01.1970;cookie1=value1;sensitiveCookie=jsonWebToken]. That cookie will be ignored.

Alle Personen, die das Log lesen können, sind nun mit diesem Cookie dazu in der Lage, sich als jemand anderes auszugeben. In der Standardkonfiguration wird dieser Eintrag beim Serverstart auf dem Level INFO geloggt, danach nur noch als DEBUG.
In Cloud-nativen Architekturen mit Microservices führt dieses Verhalten dazu, dass man nicht nur eine INFO Nachricht alle paar Tage sieht, sondern ein Vielfaches davon pro Tag. Als im Jahr 2014 diese Strategie gewählt wurde, waren Server Neustarts noch selten und das Vorgehen akzeptabel. Allerdings ist sie nicht gut gealtert, da Prozesse sich geändert haben, wodurch Server Starts inzwischen an der Tagesordnung sind.
Die begünstigenden Faktoren sind:

Wie behebe ich das Problem?

Es gibt verschiedene Möglichkeiten, das Problem zu beheben. Den Converter austauschen, die Logzeile unterdrücken oder die Fehlermeldung modifizieren. In diesem Beitrag wird nur eine leichtgewichtige Lösung betrachtet, da diese vollkommen ausreicht - nämlich die Logzeile einfach zu unterdrücken, indem die Konfiguration angepasst wird:

logging.level.org.apache.tomcat.util.http.parser.Cookie: OFF

Sollte der Logger unter einem anderen Pfad liegen, so muss dieser entsprechend angepasst werden.

Fazit

Der Standard Cookie Converter von Tomcat kann sensible Informationen loggen, aber durch ein einfaches Unterdrücken der Fehlermeldung ist der Angriff schnell und effizient verhinderbar. Sind Systeme betroffen, die ein JSON Web Token nutzen, ist es eine Überlegung wert, den best Practices zu folgen und in dem Inhalt Attribute zu hinterlegen, die sicherstellen, dass das Cookie nur auf dem Client funktioniert.

Update vom 14. Januar 2022

Die Apache Tomcat Entwickler:innen haben das potenzielle Problem analysiert und es nicht als CVE eingestuft:

“Our only official feedback on your publication is that we do not consider it a security vulnerability that warrants a CVE, coordinated disclosure”.

Dennoch wurde die entsprechende Stelle am 10. Januar angepasst, sodass im Fehlerfall nur noch nicht interpretierbare Cookie-Werte geloggt werden. Durch diese Änderungen ist es hinreichend unwahrscheinlich, dass schützenswerte Cookies geloggt werden. Die Änderung wird voraussichtlich in das nächste offizielle Tomcat Release einfließen.

Du liest die deutsche Version dieses Artikels. Klicke hier, um zur englischen Version des Artikels zu springen.