Sécurité des websockets
Websocket = (web temps réel) + X (nouveaux challenges de la sécurité web)
Les avancées majeures dans les réseaux de télécommunications filaires et mobiles ainsi que l'introduction de la fibre optique, le wifi, la 3G ou maintenant la 4G accompagnées d'une baisse des coûts utilisateurs ont vulgarisé les services internet.
Également l'arrivée sur le marché de Smartphones, tablettes ou autres objets connectés a accru le besoin d'interactivité et de temps réel.
Le World Wide Web (www), l'un des services internet les plus utilisés repose sur le protocole HTTP (HyperText Transfer Protocol) qui a toujours constitué un élément de vulnérabilité car pouvant exposer le système d'information aux attaques externes. Des dispositifs et méthodes ont été conçus dès lors pour réduire les risques en normalisant et inspectant le trafic HTTP.
Les nouvelles évolutions du WEB notamment le protocole websocket qui vient enrichir le HTTP vise à répondre au besoin de temps réel sur le web.
L'objectif de cet article est de présenter l'évolution du HTTP, les principes de base du protocole websocket, les avantages, les risques de sécurité liés à son déploiement et répondre aux deux questions ci-dessous :
- Pourquoi le websocket pose de nouveaux challenges aux dispositifs de filtrage et protection web actuels notamment les firewalls applicatifs, les proxys ou les antivirus ?
- Quels sont les mesures de contrôle à prendre en compte lors du déploiement de service web utilisant le websocket ?
1- Historique du protocole http
Le protocole HTTP a été introduit comme support du web permettant la visualisation de contenus disponibles sur des serveurs internet. Il s'agit d'un protocole applicatif au niveau 7 du modèle OSI.
Par la suite les nombreuses évolutions du protocole HTTP ont étendu les types de contenus supportés avec l'intégration des types MIME mais surtout ont amélioré les performances notamment les temps de chargement des pages web et réduit le besoin en bande passante.
HTTP 0.9
Principes
La version 0.9 pose les bases du protocole HTTP comme un protocole client serveur sans état.
- connexion du client HTTP
- envoi d'une requête de méthode GET
- réponse du serveur HTTP
le serveur ferme la connexion pour signaler la fin de la réponse.
Exemple d'échange
GET /index.html
[data]
HTTP 1.0
Principes
La version 1.0 introduit le support du cache et de la compression pour améliorer les temps de chargement.
Exemple d'échange
GET / HTTP/1.0
User-Agent: curl/7.35.0
Accept: */*
HTTP/1.0 200 OK
Date: Sun, 11 Oct 2015 14:49:42 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Accept-Ranges: none
Vary: Accept-Encoding
[data]
HTTP 1.1
Principes
La version 1.1 optimise les performances réseaux par l'introduction de la compression de bout-en-bout, une meilleure gestion du cache et de la persistance avec l'apport du multiplexage de requêtes (pipelining).
On note une diminution du nombre de connexions.
Exemple d'échange
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: www.google.fr
Accept: */*
Accept-Encoding:gzip, deflate
Connection: keep-alive
HTTP/1.1 200 OK
Date: Sun, 11 Oct 2015 14:57:21 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Accept-Ranges: none
Vary: Accept-Encoding
Transfer-Encoding: chunked
Keep-Alive: timeout=15, max=100
Accept-Encodinggzip, deflate
Connection: Keep-Alive
[data]
HTTP/2
Principes
Le protocole HTTP/2 qui est une standardisation du protocole SPDY de Google apporte des mécanismes d'amélioration du temps de chargement et une réduction de la bande passante consommée en introduisant des règles de priorité et en éprouvant les techniques de compression notamment des entêtes HTTP et le multiplexage de transfert sur une seule connexion TCP. Le HTTP/2 introduit le concept de communication bidirectionnelle full/duplex entre le client et le serveur mais avec des limites au niveau de l'interactivité.
En effet les communications du serveur vers le client se limitent à l'ajout de données dans le cache du navigateur et ne permettent pas l’échange d'événements.
Il n'y a plus de notion de requêtes/réponses mais plutôt de flux de donnée (stream) composé de trame (frame). Ainsi plusieurs « stream » peuvent être échangés de manière bidirectionnelle entre le client et le serveur sur une unique connexion TCP et ceci de façon asynchrone sans respect de l'ordre, ce qui est une révolution par rapport au multiplexage de requêtes (pipelining) HTTP1.1 pour lequel l'ordre d'envoi doit correspondre l'ordre de réception.
Exemple d'échange
GET /demo/tile-16.png HTTP/1.1
Host: http2.demo.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: fr,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
HTTP/2.0 200 OK
Server: Apache
Etag: "6791495efa96b37a4b3933f5e8bef60d:1425453546"
Last-Modified: Wed, 04 Mar 2015 07:19:06 GMT
Accept-Ranges: bytes
Content-Length: 764
Content-Type: image/png
Expires: Mon, 12 Oct 2015 22:41:45 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Mon, 12 Oct 2015 22:41:45 GMT
access-control-max-age: 86400
Access-Control-Allow-Credentials: false
access-control-allow-headers: *
access-control-allow-methods: GET,HEAD,POST
access-control-allow-origin: *
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Firefox-Spdy: h2
[data]
Version | Fonctionnalités | Performance | Sécurité |
HTTP 0.9 | Document: Text/html Méthode: GET | ||
HTTP 1.0 | Documents: MIME Nouvelles Méthodes: POST, HEAD, PUT .. | Introduction du Cache Introduction de la Compression Expérimentation de la persistance de connexion | Authentification: basic digest |
HTTP 1.1 | Nouvelles Méthodes: OPTION Entête: HOST, Upgrade | Amélioration de cache Persistance de connexion par défaut Introduction du multiplexage de plusieurs requêtes sur une même connexion de façon synchrone. Compression bout-à-bout | |
HTTP 2.0 | Compression des entêtes Priorisation des données chargées Multiplexage de plusieurs requêtes concurrentes asynchrones Utilisation d'une seule connexion tcp entre le navigateur client et le serveur pour réduire le risque de congestion réseau. protocole binaire Communication bidirectionnelle avec push du serveur vers le navigateur client | Intégration optionnelle du TLS pour la phase d'établissement de connexion (La plus part des navigateurs implémente TLS par défaut) |
2- Principes du protocole websocket
Le protocole websocket qui est un composant du HTML5 est un protocole indépendant du HTTP mais qui dans sa première phase d'établissement de connexion se base sur les échanges d'entêtes HTTP 1. 1 upgrade.
Le protocole websocket utilise HTTP lors de sa phase d'établissement de connexion mais change en profondeur le paradigme sans état qui caractérise HTTP.
Le websocket permet l'établissement d'une connexion bidirectionnelle entre le client et le serveur comme HTTP/2 et apporte également plus d'interactivité en permettant d'échanger des événements auxquels peut réagir automatiquement le navigateur client. En effet le protocole websocket propose une interface de programmation (API) permettant l'échange d'événements entre le client et le serveur.
Le websocket est donc définit par deux standards :
- L'API HTML 5 Websocket : API javascript définit par le W3C (Wide Web Consortium) Draft Juin 2014
- Le protocole Websocket : RFC 6455 Draft Mars 2013 définit par l'IETF (Internet Engineering Task Force)
Le protocole websocket améliore la latence et réduit le besoin en bande passante par un abandon d'entête HTTP réduisant ainsi le surdébit protocolaire.
L'absence d'entête oblige la définition du protocole (méthodes, actions, réponses, événements) de communication au niveau de chaque application websocket. En effet le client et le serveur doivent construire leurs propres messages. Il est possible de spécifier le type de protocole transporté par le websocket lors de la phase d'établissement de connexion via l'entête Sec-WebSocket-Protocol.
Cette flexibilité du protocole permet de pouvoir transférer tout type de donnée ou d'invoquer tout type d'action sur une communication websocket. Ainsi le websocket supporte autant le transfert de texte que de binaire. Cette souplesse qui constitue l'une des principales richesses du protocole constitue également le problème majeur dans la normalisation du trafic websocket nécessaire à son filtrage par les dispositifs de sécurité actuels.
Pile protocolaire
Contrairement au protocole HTTP dans ses versions antérieur à 2.0 qui sont des protocoles basées sur du message texte lisible, le websocket est un protocole binaire comme le HTTP 2.0. Le websocket est donc basé sur un échange de données sous forme de trame dont le format est ci-dessous :
FIN
Indique la trame de fin de message
RSV1, RSV2, RSV3
Indique si une extension du protocole websocket est négociée
opcode:
%x0
Trame indiquant la continuité des données du message
%x1
Trame de type texte
%x2
Trame de type binaire
%x3-7
Réservés pour des trames de données
%x8
Trame de fermeture de connexion
%x9
Trame de requête ping
%xA
Trame de réponse pong
%xB-F
Réservés pour des trames de contrôle
MASK:
Indique si la donnée est masquée ou non
Exemple d'échange
Le protocole websocket utilise HTTP dans sa première phase d'établissement de connexion avec l'entête HTTP 1.1 upgrade.
Le client s'assure que le serveur supporte une même version du protocole websocket via l'entête
Sec-Websocket-Key qui contient un challenge sous forme de nombre aléatoire. Le serveur retourne la signature du challenge via l'entête Sec-Websocket-Accept.
Pour le protocole websocket GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
3- Implémentation de services websocket
Librairies
Il existe de nombreuses librairies côté client et serveur permettant la mise en œuvre de websocket
Librairies client | Librairies serveur |
HTML5 Socket.io fallback | Node.Js Socket.IO WebSocket-Node Ws Java Jetty JWebSocket Ruby EventMachine Python Pywebsocket Tornado Erlang Shirasu C++ libwebsockets Net SuperWebSocket |
Frameworks
Certains Framework normalisent les messages échangés via websocket notamment
meteorJS. En effet MeteorJS propose une normalisation des échanges de messages websocket en introduisant le protocole DDP (Websocket-based data protocol) .
Wikipedia a réalisé un tableau synthèse de l'implémentation actuelle du websocket.
https://en.wikipedia.org/wiki/Comparison_of_WebSocket_implementations
4- Risques liés au déploiement de websockets
Les websockets n'introduisent pas de nouvelles attaques web mais constituent plutôt un nouveau vecteur d’intrusion et d'évasion.
Vulnérabilités connues
Les vulnérabilités des websockets sont les mêmes que celles des applications web notamment :
Faiblesse du contrôle d’accès.
Le protocole websocket n'intègre aucun mécanisme d'authentification ou autorisation.
Mauvaise validation des entrées clientes par le serveur pouvant entraîner l'injection de données malveillantes.
Le deni de service par la monopolisation des ressources du serveur (mémoire, CPU).
La flexibilité du protocole websocket permet d'envoyer des trames de messages de longueurs variables. Une trop grande valeur peut entraîner une réservation importante de mémoire au niveau du serveur. Egalement, par défaut chaque connexion websocket correspond à une connexion TCP ce qui peu très vite aboutir à une saturation des ressources au niveau du serveur.
Il existe des outils permettant d'automatiser les attaques exploitant les vulnérabilités des websocket :
XenotixDDoSer : Attaque par deni de service
OWASP ZAP : recherche de vulnérabilités
Waldo : Exploitation de vulnérabilités au niveau des navigateurs clients.
Mécanismes de sécurité
Restriction du domaines origine des requêtes CORS
Le protocole websocket introduit quelques éléments de sécurité notamment par le support du CORS (Cross-origin resource sharing). En effet le serveur à la possibilité de spécifier aux navigateurs clients via l’entête Access-Control-Allow-Origin les domaines pour lesquels il accepte des requêtes ceci pour empêcher les attaques de type CSRF ( Cross-Site Request Forgery) ou le détournement de session utilisateur.
Confidentialité et Intégrité
Le protocole websocket peut être acheminé en clair ou chiffré via TLS. Le protocole websocket en clair correspond à ws://. La version chiffrée wss:// apporte les protections du protocole TLS comme la confidentialité et l'intégrité.
Le protocole websocket implémente un mécanisme de camouflage du trafic pour les équipements intermédiaires (proxy, reverse-proxy, firewall applicatif) afin d'éviter le cache incorrect de données ou des attaques de type empoisonnement de cache. Chaque trame contient une clé aléatoire de 32 bits. Une opération XOR est réalisée entre la clé aléatoire et la donnée utile pour produire un flux binaire inintelligible.
Ce mécanisme de camouflage rend également difficile l’inspection de flux websocket par les dispositifs de filtrage actuels.
Authentification et Autorisation
Le protocole websocket n'implémentant aucun mécanisme d'authentification ou d'autorisation, cela doit être assuré via TLS ou par la gestion de session au niveau de l'application.
Mécanismes d'optimisation
Le protocole websocket supporte certaines extensions activables lors de l'établissement de connexion client/serveur permettant d'optimiser la charge réseau et les ressources serveurs.
Multiplexage de connexions
Il est possible d'activer le multiplexage de connexion websocket sur une seule connexion TCP en spécifiant l’entête Sec-WebSocket-Extensions: mux lors de l'initialisation de la connexion.
Compression de flux websocket
En spécifiant le l'entête Sec-WebSocket-Extensions: permessage-deflate, il est possible d'activer la compression des données échangées via websocket.
Il faut noter que l'activation de la compression réserve de la ressource mémoire pour chaque connexion websocket. Egalement la compression de données sur un canal chiffré TLS peut exposer la communication aux attaques de type CRIME.
5- Conclusion
Les websockets apportent la réponse à la mise en œuvre du web temps-réel permettant d'améliorer l'expérience de l'utilisateur avec plus d'interactivité.
Cependant comme présenté, la flexibilité du protocole, la difficulté à normaliser les messages échangés et le camouflage des données intégré dans les échanges websockets rend le trafic inintelligible par les équipements de sécurité notamment les anti-virus, les proxys, reverse-proxys , IDS et firewalls applicatifs.
Le protocole websocket constitue donc un nouveau vecteur d'attaques web et il est nécessaire de mettre en place des mesures de contrôles lors du déploiement de nouveaux services.
Ci-dessous une liste d’éléments de mitigation à prendre en compte lors de l'implémentation de websocket :
- Mise en place d'un mécanisme d'authentification et autorisation
- Mise en place de canal chiffré via TLS
- Restrictions des domaines origines autorisés à envoyer des requêtes au serveur
- Limitation de la taille des trames
- Contrôle du type de trame websocket échangé
- Restriction du type de protocole/message échangé via le websocket pour palier la
- complexité de normalisation du trafic websocket.
- Implémentation du multiplexage de connexion websocket
- Restriction du nombre de connexions actives par client
Références
http://www.html5rocks.com/en/tutorials/websockets/
https://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-11
https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19#page-28
https://tools.ietf.org/html/rfc6455
https://community.qualys.com/blogs/securitylabs/2012/08/03/the-tiny-mighty-waldo
http://www.securitytube.net/video/8104
https://www.chromium.org/spdy/spdy-whitepaper