De WebSocket-server in sgcWebSockets verstevigen

· Componenten

Een WebSocket-server die aan het publieke internet hangt, is een aanlokkelijk doelwit. Het protocol kent geen ingebouwde limiet voor de berichtgrootte, dus één enkele verbinding kan proberen het hele proces onderuit te halen met één geprepareerd frame, en de upgrade-handshake is een makkelijke plek om naar slordige validatie te zoeken. De nieuwste sgcWebSockets levert een reeks beschermingen die deze deuren standaard sluiten, zodat je server overeind blijft, zelfs onder vijandig verkeer.

Alles hieronder geldt voor alle drie de WebSocket-servers: TsgcWebSocketServer, TsgcWebSocketHTTPServer en de op http.sys gebaseerde TsgcWebSocketServer_HTTPAPI. De .NET-editie erft dezelfde beschermingen, omdat die op dezelfde native bibliotheek draait.

Eén limiet die drie geheugenaanvallen tegenhoudt

De belangrijkste toevoeging is één enkele eigenschap, MaxMessageSize, die begrenst hoe groot een inkomend bericht mag zijn. Standaard staat die op 64 MB, wat voor vrijwel elke toepassing ruim voldoende is, en je kunt die verhogen of verlagen, of op 0 zetten om de limiet uit te schakelen.

Die ene eigenschap verdedigt tegen drie verschillende technieken om het geheugen uit te putten, die allemaal op dezelfde manier eindigen, met de server zonder RAM:

In elk geval wordt de verbinding netjes afgesloten met WebSocket close code 1009 (Message Too Big), en het geheugen van de server komt nooit boven de limiet uit.

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;

Veilig parseren van de framelengte

WebSocket-frames kunnen een 64-bit lengteveld bevatten. Volgens RFC 6455 moet de meest significante bit van dat veld nul zijn. sgcWebSockets wijst nu een frame af waarvan de 64-bit lengte de hoogste bit gezet heeft in plaats van die te vertrouwen, zodat de bovenstaande groottelimiet niet kan worden omzeild met een integer die overloopt. Deze controle staat altijd aan en is niet afhankelijk van MaxMessageSize.

Strengere handshakes

Twee nieuwe opties onder SecurityOptions verstevigen de WebSocket-upgrade zelf, en beide staan standaard aan.

EnforceWebSocketVersion beantwoordt elke handshake die om een andere versie dan 13 vraagt met 426 Upgrade Required en een Sec-WebSocket-Version: 13-header, in plaats van de upgrade te voltooien. ValidateWebSocketKey wijst, met 400 Bad Request, elke handshake af waarvan de Sec-WebSocket-Key ontbreekt of geen geldige base64-nonce van 16 bytes is. Beide controles gelden alleen voor het RFC 6455-pad, dus oudere clients op verouderde specificaties worden niet geraakt.

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;

Hoe het past bij de firewall

Deze beschermingen leven op de protocollaag, binnen de frame-parser, wat precies de plek is waar de geheugenaanvallen plaatsvinden. Dat is het deel dat de Firewall- en RateLimiter-componenten niet kunnen bereiken, omdat zij een bericht pas zien nadat het is gedecodeerd. De twee lagen vullen elkaar aan: blijf de firewall en de rate limiter gebruiken voor IP-filtering, limieten op verbindings- en berichtsnelheid en originbeleid, en laat de nieuwe ingebouwde limieten de parser zelf bewaken. Voor een publieke server raden we aan MaxMessageSize in te stellen op je echte maximum, OriginsAllowed te vergrendelen op je front-end, en MaxConnections te begrenzen.

Bijwerken

De nieuwe beschermingen zijn actief zodra je bijwerkt, met veilige standaardwaarden, dus de meeste servers krijgen de geheugen- en handshakeversteviging zonder ook maar één regel code te wijzigen. Als je toepassing legitiem berichten groter dan 64 MB uitwisselt, verhoog dan MaxMessageSize dienovereenkomstig. Bestaande clientcode wordt niet geraakt.

Werk bij vanaf de downloadpagina van sgcWebSockets, of haal het op via GetIt of je geregistreerde account.

Vragen, feedback of hulp bij de migratie? Neem contact op, je krijgt antwoord van de mensen die de code hebben geschreven.