Un serveur WebSocket parle presque toujours aussi le HTTP : il sert la page qui ouvre le socket, répond aux vérifications de santé, héberge une API ou redirige vers votre interface. Cette surface HTTP possède ses propres classes d'attaques bien connues, et le dernier sgcWebSockets ferme les plus importantes par défaut. Cela s'applique aux deux serveurs HTTP : le TsgcWebSocketHTTPServer basé sur Indy et le TsgcWebSocketServer_HTTPAPI basé sur http.sys de Windows.
La traversée de chemin est verrouillée
Si vous servez des fichiers statiques en définissant DocumentRoot, le serveur construisait auparavant le chemin du fichier en joignant la racine du document au chemin de la requête. Une requête comme GET /../../../../windows/win.ini, ou sa forme encodée en URL /..%2f..%2f..., pouvait sortir de la racine web et lire des fichiers arbitraires. Le serveur canonicalise désormais le chemin résolu et ne le sert que s'il reste à l'intérieur de DocumentRoot ; tout ce qui en sort est rejeté. C'est toujours actif, à la fois sur les chemins HTTP/1.x et HTTP/2, et ne nécessite aucune configuration.
Limiter le corps de la requête
Le corps d'une requête HTTP n'a pas de limite de taille intégrée, donc un client pourrait déclarer un Content-Length énorme et envoyer des gigaoctets en flux pour épuiser la mémoire du serveur. La nouvelle propriété MaxRequestBodySize la plafonne. Elle vaut par défaut 64 MB et une requête qui en déclare davantage est rejetée avec un 413 avant que le corps ne soit mis en mémoire tampon. Augmentez-la pour les téléversements volumineux, ou définissez-la à 0 pour désactiver la limite.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 80;
oServer.MaxRequestBodySize := 16 * 1024 * 1024; // 16 MB, reject larger with 413
oServer.Active := True;
Une analyse de requête plus stricte arrête le smuggling
Le request smuggling HTTP exploite les serveurs qui ne s'accordent pas sur l'endroit où une requête se termine et où la suivante commence, typiquement en envoyant à la fois un en-tête Content-Length et un en-tête Transfer-Encoding: chunked. La nouvelle propriété StrictRequestParsing, activée par défaut, rejette de telles requêtes ambiguës avec un 400 et applique une validation plus stricte de l'encodage chunked, de sorte qu'un proxy frontal et le serveur ne puissent pas être désynchronisés.
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.StrictRequestParsing := True; // default: reject Content-Length + Transfer-Encoding
oServer.MaxRequestBodySize := 64 * 1024 * 1024;
oServer.Active := True;
Défense contre HTTP/2 Rapid Reset
L'attaque HTTP/2 Rapid Reset (CVE-2023-44487) ouvre un flux et l'annule immédiatement avec RST_STREAM, dans une boucle serrée, forçant le serveur à effectuer un travail de requête illimité à un coût presque nul pour le client. Le serveur HTTP/2 plafonne désormais le nombre de réinitialisations et de trames de contrôle qu'une seule connexion peut envoyer, embarque une valeur par défaut finie de 100 flux concurrents, et ferme une connexion abusive avec une trame GOAWAY. HTTP/2 est optionnel, donc cela n'a d'importance que si vous l'avez activé, mais si c'est le cas, la défense est automatique.
Des en-têtes de réponse plus propres
Lorsqu'une application construit un en-tête de réponse à partir de données influencées par la requête, par exemple une cible de redirection ou un tag d'entité, un retour chariot ou un saut de ligne glissé dans cette valeur pourrait fractionner la réponse et injecter des en-têtes supplémentaires. Le serveur http.sys supprime désormais CR et LF des valeurs d'en-tête de réponse telles que Location, Server et ETag, de sorte qu'une seule valeur ne puisse plus devenir deux en-têtes.
Où se situe le pare-feu
Ces protections résident dans l'analyseur HTTP et le serveur de fichiers propres au serveur, qui est la couche que les composants Firewall et RateLimiter ne peuvent pas atteindre. Continuez à utiliser le pare-feu pour le filtrage IP, les limites de débit et la politique d'origine, et laissez les défenses intégrées protéger l'analyse et le service statique. Pour un serveur public, nous recommandons aussi de ne définir DocumentRoot que lorsque vous servez réellement des fichiers, d'ajuster MaxRequestBodySize à votre maximum réel, et de plafonner MaxConnections.
Mise à niveau
Les nouvelles protections sont actives dès que vous mettez à jour, avec des valeurs par défaut sûres, de sorte que la plupart des serveurs gagnent ce renforcement sans modification de code. Si votre application accepte des corps de requête supérieurs à 64 MB, augmentez MaxRequestBodySize en conséquence. Les clients existants ne sont pas affectés.
Mettez à jour depuis la page de téléchargement sgcWebSockets, ou récupérez-le via GetIt ou votre compte enregistré.
Des questions, des retours ou besoin d'aide pour la migration ? Contactez-nous, vous recevrez une réponse des personnes qui ont écrit le code.
