L’annonce de la faille de sécurité a été publiée officiellement le 20 avril dernier, en même temps que les versions correctives de LemonLDAP::NG : 2.22.3, 2.21.4 et 2.16.8.
Un bug Nginx dans la gestion de l’en-tête HTTP Host a de graves conséquences pour LemonLDAP::NG qui se base sur cette information pour calculer les droits d’accès d’un utilisateur. Ainsi une requête malveillante plaçant une valeur de l’en-tête Host différente de l’URL demandée peut permettre d’hériter des droits d’une application pour accéder à une autre.
Nous expliquons dans cet article le fonctionnement exact de cette faille de sécurité et comment s’en protéger.
Host moi d’un doute
En HTTP, la notion de host correspond au nom DNS du site web que nous cherchons à contacter. Connaître l’IP du serveur qui héberge (host en anglais) ce site n’est pas suffisant car, dans la majeure partie des cas, le serveur contient différents sites, et pour savoir lequel afficher, il fait confiance au host envoyé par le client (généralement le navigateur internet de l’utilisateur). C’est également vrai dans le cas d’un mandataire inverse (reverse proxy) qui peut transmettre cette information au serveur qu’il protège, afin que ce dernier sache également quel site il doit présenter.
Le standard HTTP indique que le client doit envoyer l’information dans l’en-tête Host, pour des questions de compatibilité avec HTTP/1.0 :
A client MUST send a Host header field in an HTTP/1.1 request even if the request-target is in the absolute-form, since this allows the Host information to be forwarded through ancient HTTP/1.0 proxies that might not have implemented Host.
La RFC 9112 précise par contre que cet en-tête Host ne doit pas être utilisé tel quel par le serveur et doit être remplacé par le nom d’hôte de la cible :
When a proxy receives a request with an absolute-form of request-target, the proxy MUST ignore the received Host header field (if any) and instead replace it with the host information of the request-target. A proxy that forwards such a request MUST generate a new Host field value based on the received request-target rather than forward the received Host field value. When an origin server receives a request with an absolute-form of request-target, the origin server MUST ignore the received Host header field (if any) and instead use the host information of the request-target. Note that if the request-target does not have an authority component, an empty Host header field will be sent in this case.
Il se trouve que Nginx ne suivait pas cette recommandation, et que, dans les versions antérieures à 1.29.5, l’en-tête Host envoyé par le client n’était pas vérifié ni remplacé.
Pour des sites internets classiques, cela ne porte pas à conséquence. Mais pour LemonLDAP::NG, qui s’appuie sur le nom d’hôte envoyé pour appliquer les droits d’accès via son Handler, cela ouvre une faille critique : on peut accéder à une application B en indiquant qu’on demande l’application A, LemonLDAP::NG applique alors les droits d’accès liés à l’application A alors que les requêtes vont sur l’application B.
Exemple de requête avec curl :
curl -v \
--cookie "lemonldap=xxx" \
--header 'Host: appli-a.example.com' \
--request-target 'https://appli-b.example.com/' \
https://appli-b.example.com/
Cela ne concerne pas les applications connectées à LemonLDAP::NG via les protocoles CAS, SAML ou OpenID Connect, uniquement les applications protégées par le Handler. Malheureusement c’est le cas par défaut du Manager (interface d’administration) qui pourrait donc être accessible à des utilisateurs non privilégiés.
Pour résumer, les installations de LemonLDAP::NG qui sont concernées par cette faille sont celles qui vérifient toutes les affirmations suivantes :
- Version de LemonLDAP::NG installée avant la sortie des versions correctives (2.22.3, 2.21.4 et 2.16.8) et dont les configurations n’ont pas été corrigées (voir plus loin dans notre article),
- Utilisation du serveur web Nginx avec une version inférieure à 1.29.5,
- Protection d’une application avec un Handler, y compris le Manager (sauf si son mode de protection a été changé pour ne plus utiliser le Handler),
- Pas d’utilisation d’autres logiciels en coupure entre les clients et le serveur LemonLDAP::NG, comme par exemple HAProxy.
Au pied de l’alerte
La gravité de la situation a amené l’équipe de développement de LemonLDAP::NG à alerter l’équipe Nginx, les distributions fournissant officiellement des paquets (Debian, EPEL), et l’ANSSI.
Le bug n’étant pas situé dans le code source de LemonLDAP::NG, la meilleure solution aurait été la diffusion d’une mise à jour de sécurité de toutes les installations Nginx mais la communauté Nginx n’a pas considéré le problème comme assez important pour déclencher ce dispositif.
L’autre solution était la modification des différents fichiers de configuration des hôtes virtuels Nginx afin de ne plus utiliser l’en-tête Host mais passer directement le nom d’hôte correspondant à l’hôte virtuel au Handler LemonLDAP::NG.
Ces modifications ont été faites dans les fichiers fournis dans les paquets, et les versions 2.22.3, 2.21.4 et 2.16.8 de LemonLDAP::NG ont été publiées. Mais mettre à jour son installation ne suffit pas : puisqu’il s’agit de fichiers de configuration, ils ne sont pas écrasés ou modifiés par la mise à jour des paquets. Les administrateurs systèmes doivent appliquer les corrections eux-mêmes.
Protection rapprochée
Il n’est pas très compliqué d’appliquer les modifications nécessaires, mais il faut s’assurer de changer l’ensemble des fichiers de configuration des hôtes virtuels liés à LemonLDAP::NG (Portail, Manager, toutes les applications protégées par le Handler).
Deux cas se présentent :
- Les configurations définissant le paramètre
HOST, qu’il faut dans ce cas remplacer parHTTP_HOSTen l’associant à la valeur$host - Les configurations ne définissant pas le paramètre
HOST, il faut alors ajouter la définition deHTTP_HOST, toujours en l’associant à la valeur$host
Ainsi la configuration suivante :
fastcgi_param HOST $http_host;
# or if using uwsgi server:
#uwsgi_param HOST $http_host;
Deviendra :
fastcgi_param HTTP_HOST $host;
# or if using uwsgi server:
#uwsgi_param HTTP_HOST $host;
Et les configurations qui ne définissaient pas HTTP_HOST devront le faire.
Nous préconisons également de passer en revue les configurations “proxy” afin qu’elles forcent la valeur de l’en-tête Host tranmsmise aux applications protégées.
Remplacer :
proxy_set_header Host $http_host;
Par :
proxy_set_header Host $host;
Besoin d’un coup de main ?
Cet article vous aura fourni toutes les informations pour vérifier que votre installation de LemonLDAP::NG était sécurisée, et pour effectuer les corrections de configurations si elles étaient nécessaires.
Bien entendu, nous sommes à votre disposition pour vous aider à faire le diagnostic de vos serveurs et mettre en place les bonnes configurations, n’hésitez pas à nous contacter !