Le 18 juillet 2016, une vulnérabilité nommée « HTTPoxy » a été annoncée, affectant certaines applications Web côté serveur qui s'exécutent dans des environnements CGI ou de type CGI, comme certaines configurations FastCGI. Les langages concernés jusqu'à présent sont PHP, Python et Go.
Un certain nombre de CVE ont été attribués, couvrant des langages spécifiques et des implémentations CGI :
Il existe un nouveau site Web décrivant la vulnérabilité , une note de vulnérabilité CERT et une description de la découverte de la vulnérabilité . Vous trouverez des informations supplémentaires sur le site Web personnel de Dominic Scheirlinck , développeur Web open source chez Vend.
Cet article décrit la vulnérabilité et explique comment utiliser NGINX ou NGINX Plus pour contrer les tentatives d’exploitation sur vos serveurs.
La vulnérabilité existe en raison d’un conflit d’espace de noms. Une interface de type CGI ou FastCGI définit des variables d’environnement en fonction des paramètres de requête HTTP, et celles-ci peuvent remplacer les variables internes utilisées pour configurer l’application.
Actuellement, le seul exploit connu de cette vulnérabilité concerne les applications Web exécutées dans des environnements CGI et de type CGI qui utilisent certaines bibliothèques clientes HTTP pour effectuer des requêtes HTTP vers d’autres services. Dans ce cas, les attaquants peuvent potentiellement rediriger les requêtes internes générées par l’application vers un serveur de leur choix, et ainsi capturer toutes les données secrètes contenues dans les requêtes, comme indiqué ci-dessous.
Vous pouvez utiliser NGINX ou NGINX Plus pour identifier et contrer les tentatives d’exploitation de cette vulnérabilité. Cela constitue un moyen efficace de prévenir toute attaque, vous donnant ainsi le temps d’auditer et de mettre à jour tout code affecté.
Pour comprendre le fonctionnement de cette vulnérabilité et comment protéger votre site contre elle, il faut comprendre comment les interfaces CGI et de type CGI définissent les variables d’environnement et comment certaines bibliothèques d’applications sont configurées par des variables d’environnement.
De nombreuses plates-formes d’applications Web utilisent des interfaces CGI ou de type CGI pour connecter des applications à un serveur Web. Ces interfaces convertissent les en-têtes d'une requête HTTP en variables d'environnement préfixées par HTTP_
. Une application peut ensuite rechercher la valeur des en-têtes de requête (tels que l' User-Agent
) en inspectant son environnement.
Un client peut créer des variables d'environnement arbitraires (commençant par HTTP_
) dans l'environnement de l'application en envoyant des requêtes avec l'en-tête approprié. Par exemple, l'en-tête de requête Foo:
bar
devient la variable d'environnement HTTP_FOO=bar
.
Certaines plateformes fournissent une couche d'abstraction qui masque les variables d'environnement, telles que la variable globale $_SERVER
de PHP. Néanmoins, ces abstractions sont construites sur la base des pratiques standard CGI et FastCGI de définition de variables d'environnement.
Par exemple, lorsqu'elle s'exécute en mode FastCGI, une application PHP peut déterminer l'en-tête User-Agent
d'une requête comme suit :
// les deux méthodes renvoient le même résultat$useragent = getenv( 'HTTP_USER_AGENT' );
$useragent = $_SERVER['HTTP_USER_AGENT'];
Une application Web complexe extrait des fonctionnalités de bibliothèques externes. Par exemple, les applications doivent parfois effectuer des requêtes HTTP vers d’autres services (à la manière des microservices) et elles peuvent utiliser l’une des bibliothèques tierces courantes pour le faire. Ces bibliothèques prennent souvent en charge une fonctionnalité appelée proxy HTTP , qui est un serveur intermédiaire utilisé pour relayer la requête HTTP.
Une manière simple de configurer une bibliothèque comme celle-ci est de définir la configuration via des variables d'environnement. La bibliothèque PHP Guzzle, largement utilisée, est configurée en partie par une variable d'environnement nommée HTTP_PROXY
, qui est définie sur l'adresse d'un serveur proxy. Si HTTP_PROXY
est défini de cette manière, la bibliothèque relaie alors toutes les requêtes HTTP qu'elle génère à l'adresse du serveur proxy. Le package net/http
de Go et le module Requests de Python font également confiance à la variable d'environnement HTTP_PROXY
et l'interprètent de la même manière.
Les bibliothèques décrites dans l’élément 2 n’ont pas été conçues avec des interfaces CGI ou de type CGI à l’esprit, et la variable d’environnement HTTP_PROXY
à laquelle elles font confiance chevauche l’espace de noms HTTP_
utilisé par les interfaces CGI et FastCGI comme indiqué dans l’élément 1.
En définissant la valeur de la variable d’environnement HTTP_PROXY
sur une adresse de leur choix, les attaquants peuvent rediriger et capturer les requêtes HTTP internes générées par l’application. Ces demandes peuvent contenir des informations sensibles, telles que des clés d’authentification et des données privées, et elles peuvent révéler des informations sur des API et des points de terminaison supplémentaires qui peuvent être exploités.
Un attaquant peut le faire en envoyant une requête avec un en-tête Proxy
, et l’interface CGI ou FastCGI crée docilement une variable d’environnement nommée HTTP_PROXY
pour cette invocation de l’application. Notez que seules les requêtes contenant l’en-tête Proxy
erroné sont directement affectées.
La vulnérabilité HTTPoxy n'affecte pas directement NGINX, mais NGINX et NGINX Plus peuvent être utilisés pour arrêter les attaques basées sur cette vulnérabilité.
Vous pouvez utiliser NGINX pour « assainir » l’entrée de l’application en définissant le paramètre HTTP_PROXY
FastCGI sur la chaîne vide. Cela supprime complètement le paramètre de la requête FastCGI :
fastcgi_param HTTP_PROXY "";
Lors de la transmission par proxy de requêtes HTTP à une application en amont, il est judicieux de définir tout en-tête Proxy
sur une chaîne vide, au cas où l'application en amont s'exécuterait sur une plate-forme vulnérable :
proxy_set_header Proxy "";
Le proxy
n'est pas un en-tête HTTP standard , donc toutes les requêtes contenant cet en-tête peuvent être considérées comme suspectes. Vous pouvez utiliser NGINX ou NGINX Plus pour enregistrer ces requêtes suspectes dans un journal d'accès dédié, ici nommé badactor.log :
# définir le format 'proxylog' dans le contexte http{} :log_format proxylog '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_proxy"';
# enregistrer les requêtes avec un en-tête Proxy en utilisant le format 'proxylog'
access_log /var/log/nginx/badactor.log proxylog if=$http_proxy;
Note : Dans le contexte de configuration où vous placez cette directive access_log
, elle remplace toute journalisation d'accès définie à un niveau supérieur dans la configuration NGINX.
NGINX et NGINX Plus offrent un moyen efficace de surveiller et de vaincre l'attaque HTTPoxy. Utilisez les techniques décrites ci-dessus pour protéger votre application pendant que vous auditez, mettez à jour et testez votre code pour supprimer la vulnérabilité.
Si vous avez des questions, veuillez commenter cet article – ou, si vous êtes abonné à NGINX Plus, n'hésitez pas à contacter notre équipe d'assistance pour obtenir de l'aide.
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."