A WebSocket server almost always speaks HTTP too: it serves the page that opens the socket, answers health checks, hosts an API, or redirects to your front end. That HTTP surface has its own well-known attack classes, and the latest sgcWebSockets closes the most important ones by default. This applies to both HTTP servers: the Indy-based TsgcWebSocketHTTPServer and the Windows http.sys based TsgcWebSocketServer_HTTPAPI.
Path traversal is sealed
If you serve static files by setting DocumentRoot, the server used to build the file path by joining the document root to the request path. A request like GET /../../../../windows/win.ini, or its URL-encoded form /..%2f..%2f..., could walk out of the web root and read arbitrary files. The server now canonicalizes the resolved path and serves it only when it stays inside DocumentRoot; anything that escapes is rejected. This is always on, on both the HTTP/1.x and HTTP/2 paths, and needs no configuration.
Bounding the request body
An HTTP request body has no built-in size limit, so a client could declare a huge Content-Length and stream gigabytes to exhaust server memory. The new MaxRequestBodySize property caps it. It defaults to 64 MB and a request that declares more is rejected with 413 before the body is buffered. Raise it for large uploads, or set it to 0 to disable the limit.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 80;
oServer.MaxRequestBodySize := 16 * 1024 * 1024; // 16 MB, reject larger with 413
oServer.Active := True;
Stricter request parsing stops smuggling
HTTP request smuggling abuses servers that disagree on where one request ends and the next begins, typically by sending both a Content-Length and a Transfer-Encoding: chunked header. The new StrictRequestParsing property, enabled by default, rejects such ambiguous requests with 400 and applies stricter chunked-encoding validation, so a front-end proxy and the server cannot be desynchronized.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.StrictRequestParsing := True; // default: reject Content-Length + Transfer-Encoding
oServer.MaxRequestBodySize := 64 * 1024 * 1024;
oServer.Active := True;
HTTP/2 Rapid Reset defense
The HTTP/2 Rapid Reset attack (CVE-2023-44487) opens a stream and immediately cancels it with RST_STREAM, in a tight loop, forcing the server to do unbounded request work at almost no cost to the client. The HTTP/2 server now caps how many resets and control frames a single connection may send, ships a finite default of 100 concurrent streams, and closes an abusive connection with a GOAWAY frame. HTTP/2 is opt-in, so this only matters if you enabled it, but if you did, the defense is automatic.
Cleaner response headers
When an application builds a response header from request-influenced data, a redirect target or an entity tag for example, a carriage-return or line-feed smuggled into that value could split the response and inject extra headers. The http.sys server now strips CR and LF from response header values such as Location, Server and ETag, so a single value can no longer become two headers.
Where the firewall fits
These protections sit in the server's own HTTP parser and file server, which is the layer the Firewall and RateLimiter components cannot reach. Keep using the firewall for IP filtering, rate limits and origin policy, and let the built-in defenses guard parsing and static serving. For a public server we also recommend setting DocumentRoot only when you actually serve files, tuning MaxRequestBodySize to your real maximum, and capping MaxConnections.
Upgrading
The new protections are active as soon as you update, with safe defaults, so most servers gain the hardening without a code change. If your application accepts request bodies larger than 64 MB, raise MaxRequestBodySize accordingly. Existing clients are unaffected.
Update from the sgcWebSockets download page, or grab it through GetIt or your registered account.
Questions, feedback or migration help? Get in touch, you will get a reply from the people who wrote the code.
