Härtung des WebSocket-Servers in sgcWebSockets

· Komponenten

Ein WebSocket-Server, der dem öffentlichen Internet ausgesetzt ist, ist ein verlockendes Ziel. Das Protokoll besitzt kein eingebautes Limit für die Nachrichtengröße, sodass eine einzelne Verbindung versuchen kann, den gesamten Prozess mit einem einzigen präparierten Frame in die Knie zu zwingen, und der Upgrade-Handshake ist eine leichte Angriffsfläche, um nach nachlässiger Validierung zu suchen. Das neueste sgcWebSockets liefert eine Reihe von Schutzmechanismen, die diese Türen standardmäßig verschließen, sodass Ihr Server selbst unter feindlichem Datenverkehr verfügbar bleibt.

Alles Folgende gilt für alle drei WebSocket-Server: TsgcWebSocketServer, TsgcWebSocketHTTPServer und den auf http.sys basierenden TsgcWebSocketServer_HTTPAPI. Die .NET-Edition erbt dieselben Schutzmechanismen, da sie auf derselben nativen Bibliothek läuft.

Ein Limit, das drei Speicherangriffe stoppt

Die wichtigste Neuerung ist eine einzige Eigenschaft, MaxMessageSize, die begrenzt, wie groß eine eingehende Nachricht sein darf. Sie ist standardmäßig auf 64 MB eingestellt, was für nahezu jede Anwendung großzügig ist, und Sie können sie erhöhen oder senken oder auf 0 setzen, um das Limit zu deaktivieren.

Diese eine Eigenschaft wehrt drei verschiedene Speichererschöpfungstechniken ab, die alle auf dieselbe Weise enden, nämlich damit, dass dem Server der Arbeitsspeicher ausgeht:

In jedem Fall wird die Verbindung sauber mit dem WebSocket-Close-Code 1009 (Message Too Big) geschlossen, und der Speicher des Servers überschreitet niemals die Obergrenze.

oServer := TsgcWebSocketServer.Create(nil);
oServer.Port := 80;
// accept messages up to 16 MB, reject anything larger with close 1009
oServer.MaxMessageSize := 16 * 1024 * 1024;
oServer.Active := True;

Sicheres Parsen der Frame-Länge

WebSocket-Frames können ein 64-bit-Längenfeld tragen. Gemäß RFC 6455 muss das höchstwertige Bit dieses Feldes null sein. sgcWebSockets lehnt nun einen Frame ab, dessen 64-bit-Länge das höchstwertige Bit gesetzt hat, anstatt ihm zu vertrauen, sodass das obige Größenlimit nicht mit einer Ganzzahl umgangen werden kann, die einen Überlauf verursacht. Diese Prüfung ist immer aktiv und hängt nicht von MaxMessageSize ab.

Strengere Handshakes

Zwei neue Optionen unter SecurityOptions härten das WebSocket-Upgrade selbst, und beide sind standardmäßig aktiviert.

EnforceWebSocketVersion beantwortet jeden Handshake, der nach einer anderen Version als 13 fragt, mit 426 Upgrade Required und einem Sec-WebSocket-Version: 13-Header, anstatt das Upgrade abzuschließen. ValidateWebSocketKey lehnt mit 400 Bad Request jeden Handshake ab, dessen Sec-WebSocket-Key fehlt oder kein gültiger 16-Byte-base64-Nonce ist. Beide Prüfungen gelten nur für den RFC 6455-Pfad, sodass ältere Clients mit Legacy-Spezifikationen nicht betroffen sind.

oServer := TsgcWebSocketServer.Create(nil);
oServer.SecurityOptions.EnforceWebSocketVersion := True;  // 426 on a wrong version
oServer.SecurityOptions.ValidateWebSocketKey := True;     // 400 on a malformed key
// lock the server to your own site while you are at it
oServer.SecurityOptions.OriginsAllowed := 'https://app.example.com';
oServer.Active := True;

Wie es mit der Firewall zusammenspielt

Diese Schutzmechanismen befinden sich auf der Protokollebene, innerhalb des Frame-Parsers, also genau dort, wo die Speicherangriffe stattfinden. Das ist der Teil, den die Komponenten Firewall und RateLimiter nicht erreichen können, da sie eine Nachricht erst sehen, nachdem sie dekodiert wurde. Die beiden Ebenen ergänzen sich gegenseitig: Verwenden Sie die Firewall und den Rate Limiter weiterhin für IP-Filterung, Verbindungs- und Nachrichtenratenlimits sowie Origin-Richtlinien, und lassen Sie die neuen eingebauten Limits den Parser selbst schützen. Für einen öffentlichen Server empfehlen wir, MaxMessageSize auf Ihr tatsächliches Maximum zu setzen, OriginsAllowed auf Ihr Frontend zu beschränken und MaxConnections zu begrenzen.

Aktualisierung

Die neuen Schutzmechanismen sind aktiv, sobald Sie aktualisieren, mit sicheren Standardwerten, sodass die meisten Server die Speicher- und Handshake-Härtung ohne eine einzige Codeänderung erhalten. Wenn Ihre Anwendung legitim Nachrichten austauscht, die größer als 64 MB sind, erhöhen Sie MaxMessageSize entsprechend. Bestehender Client-Code ist nicht betroffen.

Aktualisieren Sie über die sgcWebSockets-Downloadseite oder beziehen Sie es über GetIt oder Ihr registriertes Konto.

Fragen, Feedback oder Hilfe bei der Migration? Nehmen Sie Kontakt auf, Sie erhalten eine Antwort von den Menschen, die den Code geschrieben haben.