L’adresse 0.0.0.0 au cœur d’une très vieille faille de sécurité dans les navigateurs
Supposition à tort
La société de sécurité Oligo a publié hier un billet dans lequel elle explique avoir alerté les fournisseurs de navigateurs au sujet d’une faille critique. Elle réside dans la manière dont ils gèrent l’adresse 0.0.0.0, pouvant renvoyer des pirates vers des ressources locales et une exécution de code à distance.
Le 08 août à 17h20
5 min
Sécurité
Sécurité
0.0.0.0 Day : c’est le nom donné par la société israélienne Oligo à cette faille présente dans Chrome, Firefox et Safari. Elle n’a rien de nouveau pourtant, puisqu’elle remonte dans certains cas à 18 ans. Oligo précise toutefois qu’elle a été découverte « récemment ».
L’adresse IP 0.0.0.0 est particulière et n’a pas la même signification selon le contexte. Sur Wikipédia, on trouve les deux cas les plus courants. Dans le contexte d’un serveur par exemple, elle a valeur de « toutes les adresses IPv4 de la machine locale ». Dans le domaine du routage en revanche, elle signifie le plus souvent « route par défaut ». En IPv6, plutôt que d’écrire une longue chaine de zéros, on utilise la notation « :: ».
Quel lien avec les navigateurs ? « Ce problème découle de la mise en œuvre incohérente des mécanismes de sécurité dans les différents navigateurs, ainsi que d'un manque de normalisation dans l'industrie des navigateurs », résume Oligo.
Tous les navigateurs, sauf sur Windows
La vulnérabilité trouvée est décrite comme « fondamentale » et « logique ». Elle réside aussi bien dans Chromium que dans Firefox et Safari. macOS et Linux sont concernés, mais pas Windows. Microsoft a en effet décidé de bloquer l’adresse 0.0.0.0 il y a plusieurs années.
Le problème découvert par Oligo réside dans la manière dont les navigateurs traitent les requêtes vers la fameuse adresse IP. Elle peut être utilisée pour exploiter des services locaux. Un site web public (comme les domaines finissant en .com, .fr, etc.) sont « capables de communiquer avec des services fonctionnant sur le réseau local (localhost) et potentiellement d'exécuter un code arbitraire sur l'hôte du visiteur en utilisant l'adresse 0.0.0.0 au lieu de localhost/127.0.0.1 », explique Oligo.
En clair, toute application s'exécutant sur localhost et accessible via 0.0.0.0 est susceptible d'exécuter du code à distance. Les pirates peuvent alors former une requête malveillante et l’expédier vers l’adresse 0.0.0.0 de la victime, dans l’espoir d’accéder à des ressources locales. S’ils y parviennent, de nombreuses possibilités s’ouvrent à eux, avec un vaste choix de vecteurs pour d’autres attaques.
Un grand nombre de configurations vulnérables
En pratique, Oligo estime que la faille concerne surtout les particuliers et les entreprises hébergeant des serveurs web pour certains scénarios, dont les tests en développement. Mais même ainsi, les chercheurs pensent que le nombre de configurations vulnérables est très élevé.
En mars dernier, une cyberattaque avait par exemple détourné de la puissance de calcul à des fins de minage de cryptoactifs en détournant le logiciel Ray, rapportait Forbes. Ray est utilisé par de nombreuses grandes entreprises pour l’entrainement des modèles d’IA. Une configuration à base de localhost et une API non protégée rendaient l’attaque possible. Anyscale, qui supervise le développement de Ray, avait protesté. L’entreprise renvoyait vers son guide de configuration, qui déconseillait fortement d’exposer Ray à du trafic réseau non fiable.
« Lorsque les services utilisent localhost, ils supposent un environnement contraint. Cette hypothèse, qui peut (comme dans le cas de cette vulnérabilité) être erronée, donne lieu à des implémentations de serveurs non sécurisées », résume Avi Lumelsky, principal chercheur derrière l’étude d’Oligo.
Les entreprises travaillent à colmater la brèche
Apple a confirmé auprès de Forbes travailler sur la question. Lors d’une prochaine bêta de macOS Sequoia, le problème ne devrait plus exister. Safari 18 devrait complètement bloquer l’adresse 0.0.0.0 dans le nouveau macOS. Les nouvelles versions du navigateur étant répercutées sur le système précédent, Sonoma en bénéficiera également. La situation est plus floue pour les moutures plus anciennes.
Chez Google, la prochaine révision 128 de Chrome commencera à bloquer elle aussi l’adresse 0.0.0.0. Ce changement sera déployé progressivement au cours des prochaines versions, jusqu’à un blocage total pour Chrome 133.
Dans la fiche explicative de Google, on peut lire que cette mesure est adoptée avant que Private Network Access n’entre en jeu. PNA est une spécification (toujours en brouillon) pour un mécanisme visant à limiter « la capacité des sites Web à envoyer des requêtes aux serveurs situés sur des réseaux privés ». PNA étend également le protocole CORS (Cross-Origin Resource Sharing). Avec PNA, les sites web doivent donc demander explicitement l’autorisation aux serveurs situés sur des réseaux privés pour leur envoyer des requêtes. Or, la faille découverte par Oligo permet de contourner entièrement PNA.
Chez Mozilla, c’est un peu plus compliqué. Firefox va adopter Private Network Access, mais ne compte pas bloquer immédiatement l’adresse 0.0.0.0. Le navigateur n’ayant jamais restreint l’accès au réseau privé, il n’y a pas de faille à proprement parler. Après l’avertissement d’Oligo, Mozilla a quand même proposé un changement de la spécification Fetch pour introduire le blocage 0.0.0.0. « Imposer des restrictions plus strictes comporte un risque important d'introduire des problèmes de compatibilité », a cependant déclaré Mozilla à Forbes.
Oligo présentera ses découvertes plus en détail le 10 août, lors de la DEF CON qui se tient à Las Vegas.
L’adresse 0.0.0.0 au cœur d’une très vieille faille de sécurité dans les navigateurs
-
Tous les navigateurs, sauf sur Windows
-
Un grand nombre de configurations vulnérables
-
Les entreprises travaillent à colmater la brèche
Commentaires (28)
Vous devez être abonné pour pouvoir commenter.
Déjà abonné ? Se connecter
Abonnez-vousLe 08/08/2024 à 17h45
Le 08/08/2024 à 17h51
C'est comme 1.1.1.1 utilisé en interne dans les livebox.
Modifié le 08/08/2024 à 19h05
Comme Microsoft ne suit pas les standards, pour une fois ca tombe du bon coté de la tartine pour Windows. Mais je n'appellerai pas un "bon choix" le fait de ne pas suivre les standards.
Modifié le 08/08/2024 à 19h37
Par contre, je ne vois pas pourquoi tu dis que Windows ne suit pas les standards. Pour le coup, et à ma connaissance, l'usage d'adresse 0.0.0.0 ne fait pas partie du standard (je parle bien de l'adresse, pas des blocs 0.0.0.0/8)
edit]
la [RFC 5735 section 3 précise l'usage possible de 0.0.0.0. L'IP 0.0.0.0 devrait (MAY) être utilisée qu'en tant qu'adresse source, pas en tant qu'adresse cible. Donc toute communication à destination de 0.0.0.0 devrait, d'après la compréhension que j'ai de la norme, être rejeté.
J'ai bien employé devrait pour refléter le MAY de la norme. Autrement dit, ce n'est pas une obligation, mais une recommandation forte. Allez à l'encontre n'est pas formellement interdit, mais ne va pas dans le sens de l'esprit de la norme.
Donc pour le coup, c'est même Windows qui respecte mieux la norme sur ce coup là !
[edit 2]
Pour être le plus précis possible, je suis remonté jusqu'à la RFC 1700, où le texte est beaucoup plus clair à mes yeux, et n'utilise pas MAY :
Le 08/08/2024 à 20h34
Standard était peut-être un peu fort. Cette "interprétation" de 0=localhost était dans l'implémentation de BSD qui a été reprise par les OS qui ont ré-implémentés les "BSD socket".
L'implémentation a toujours été différente coté Windows (winsock) car ils sont repartis de la spec pour leur stack réseau. Meme si on trouve du code BSD dans windows, c'est davantage pour les outils que pour la stack.
Avis perso:
Je ne pense pas que BSD ait volontairement voulu donner la sémantique INADDR_LOOPBACK (127.0.0.1) à INADDR_ANY (0.0.0.0) dans le cas d'un connect(). Ca ressemble plutôt à l'interprétation du développeur C quand il a été confronté à la valeur 0 (zéro). Comme 0 (zéro) et "0.0.0.0" ont la même représentation (0x00000000), ca sent le raccourcis logique 0 = "0.0.0.0" = pas de routage => on reste sur l'hôte local.
Avec cette faille, j'espère qu'on aura l'explication d'un vieux de la vieille sur le pourquoi. J'adore ces anecdotes sur l'archéologie des logiciels. Ex: le blog de Raymond Chen.
Le 08/08/2024 à 20h56
C'est toujours intéressant effectivement, et souvent riche en informations !
Le 09/08/2024 à 09h56
Modifié le 09/08/2024 à 12h41
- There is no mystery over who wrote the Blue Screen of Death, despite what some may want you to believe
- The origin story of the Windows 3D Pipes screen saver
- The history of Alt+number sequences, and why Alt+9731 sometimes gives you a heart and sometimes a snowman
.
Le 08/08/2024 à 19h39
Le 09/08/2024 à 09h16
https://winhelp2002.mvps.org/hosts.htm
Et je me souvenais qu'a l'époque win8, il avait changé la redirection de 127.0.0.1 vers 0.0.0.0 pour une raison dont je ne me rappelais plus mais qui est encore notée:
"The HOSTS file now contains a change in the prefix in the HOSTS entries to "0.0.0.0" instead of the usual "127.0.0.1".
This was done to resolve a slowdown issue that occurs with the change Microsoft made in the "TCP loopback interface" in Win8.1"
Peut-être qu'en réalité, c’était juste devenu plus rapide car MS s'était mis à carrément poubelliser toute trame ayant cette IP source/destination.
Probable que Microsoft ait été assez longtemps dans la même situation. De toutes manières, niveau réseau, ils ont dès le début été à la bourre (il a fallu attendre win3.11 pour avoir une pile réseau quand les unices étaient construits autour depuis les origines à la fin des années 60) et Linux n'a pas arrangé les choses: Là c'est très simple, un OS boite blanche c'est l'outil idéal pour implémenter les évolutions/nouveautés par la recherche universitaire, entre autres. Windows étant au contraire une boite noire, le choix général dans le domaine c'est surtout celui de suivre! Ce n'est pas pour rien si toute l'infra réseaux/télécoms a fait le choix de passer à Linux dans la première moitié de la décennie 2000: Les RTOS qui s'imposaient jusque là posaient le même type de problème et quand le réseau est votre cœur de métier, on va là ou l'innovation se trouve.
Le 11/08/2024 à 17h48
Je sais que l'on adore taper sur ceux qui tiennent la dragée haute des bonnes pratiques quand ils se gaussent (à raison) du cauchemar en face, parce qu'on adore tous être moralisateur, mais encore faut-il être de bonne foi pour être crédible et audible, à la fois immédiatement… et à plus long terme !
Le 08/08/2024 à 17h50
Dans tous les cas ça semble être un problème uniquement lié à des machines où des services spécifiques tournent (qui a un serveur http qui écoute sur son laptop ?) et donc non sur des machines d'usagers lambda. (un peu) ouf.
Le 08/08/2024 à 18h14
Donc oui, ça ne touche que les machines qui ont des services réseau qui tournent localement, mais ça touche... toutes les machines qui ont des services réseau qui tournent localement. J'imagine qu'on peut avoir un proof of concept basé sur un client SMB écrit en Javascript et exécuté dans le navigateur qui passerait outre les mécanismes de sécurité placés sur 127.0.0.1 en utilisant 0.0.0.0 et qui redirigerait le contenu local vers un serveur distant.
Le 08/08/2024 à 18h52
Utiliser 0.0.0.0 est courant en IPv4 car pas mal de services tournent sur des vm ou conteneurs avec une adresse locale et un NAT44
En IPv6, on peut utiliser des adresses de service qui sont passées en argument au conteneurs et permettre au service de n'écouter que sur l'adresse dédiée. Si un accès de test est désiré, il est possible d'utiliser une adresse ULA en plus.
Modifié le 08/08/2024 à 19h10
if (!fl4->daddr) fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
net/ipv4/route.c
Le 08/08/2024 à 21h45
(pénible le markdown pipé...)
C'est donc dès la ligne « fl4->daddr = fl4->saddr » qu'une requête provenant de 127.0.0.1 et destinée à 0.0.0.0 devient destinée à 127.0.0.1
Et cela interdit donc de bloquer ces requêtes via le pare-feu.
Le 09/08/2024 à 12h29
1. si pas d'adresse de destination, alors destination = source.
2. si pas d'adresse de destination ni d'adresse source, alors destination = source = localhost.
C'est ce que fait le code, même si ce n'est pas très lisible :)
Le 09/08/2024 à 13h23
En cas d'arrivée d'un paquet IPv4 d'un navigateur, l'adresse source sera 127.0.0.1 et c'est la ligne que j'ai donné qui cause le remplacement de 0.0.0.0 par 127.0.0.1
Je suis du même avis que tous ceux qui pensent que cela devrait provoquer le rejet du paquet.
Le 09/08/2024 à 10h19
Autre point d'ailleurs, les navigateurs bloquent les ports connus standard :
https://searchfox.org/mozilla-central/source/netwerk/base/nsIOService.cpp#152
Donc justement on se limite quand même sacrément au niveau des services qui pourraient être accessibles en 0.0.0.0:. (Bon ton exemple de SMB typiquement n'est pas dans la liste des ports bloqués… donc OK, mais pour moi la faille de sécurité est aussi présente avec 127.0.0.1)
Le 09/08/2024 à 11h37
Si tu saisis l'adresse loopback (typiquement 127.0.0.1) tu n'accepteras que les communications en provenance de localhost (interne = la machine).
Si tu saisi l'adresse sur le réseau local (par ex. 192.168.2.38) tu accepteras les communications provenant de l'extérieur (= extérieur à la machine, donc en provenance du réseau = externe) dès lors que l'adresse cible est 192.168.2.28. Si tu es sur ta machine et que tu essaies en loopback (via 127.0.0.1), la communication ne sera normalement pas acceptée, mais elle le sera si tu utilises l'adresse 192.168.2.28.
Si ta machine est accessible via plusieurs réseaux, si tu mets un 0.0.0.0, alors elle acceptera les communications, quel que soit le réseau. Si tu mets une adresse 192.168.2.38 comme adresse d'écoute, mais que ta machine dispose aussi de l'IP 10.0.43.23 sur un autre réseau, alors utiliser cette 2e IP (10.0.43.23) pour accéder au service ne marchera pas .
En fonction de la position du pare-feu dans le réseau, cela peut avoir une très grande importance !
Les subtilités du réseau...
Le 09/08/2024 à 17h45
Modifié le 08/08/2024 à 18h37
Le 08/08/2024 à 19h38
Le 08/08/2024 à 22h50
fetch('//0.0.0.0:8000')
dans ma console JS de mon Firefox : bloqué par uBlock Origin.Filtre qui vient à la fois de EasyPrivacy et de « uBlock filters - Quick fixes »
Donc, je pense que uBlock Origin suffit. Mais bon, hein, je dis ça, je dis rien.
Le 09/08/2024 à 06h33
Sur ton poste de travail, il y a probablement des navigateurs "cachés" comme par exemple celui qui gère les connexions WiFi (pour proposer une mire de login), ou un afficheur html dans le client mail. Et ces "navigateurs" n'ont probablement pas uBlock.
Modifié le 09/08/2024 à 09h07
Le 08/08/2024 à 23h54
dans mes références, 0.0.0.0 était une adresse non définie en adresse source et invalide en destination, je me demande qui a eu cette idée bizarre de la traiter comme localhost ou loopback, ça n'aurait pas dû arriver.
Ce n'est pas parce que netstat affiche une écoute sur 0.0.0.0 pour dire non définie que cette destination est valide, tout comme un routeur doit bloquer l'adresse avec host à 0 d'un réseau qui lui est raccordé, même si elle est présente dans sa table de routage.
Le 11/08/2024 à 17h43
Il fallait qualifier le bogue.
Puis il fallait démontrer une réelle exploitation.
Ouverture, fermeture, tergiversations… 20 ans.
Et plus le temps passait, plus la probabilité d'un traitement simple & rapide s'éloignait, par le simple fait du temps passé (qui va être entendu en questionnant 10 ans de tergiversation sans se retrouver être attaqué personnellement ?).
Messieurs dans le domaine de la sécurité, je vous propose ceci :
* Perçons ensemble l’abcès de votre ego
* Arrêtons d'emmerder les remonteurs de problèmes, et partons du principe qu'ils puissent avoir raison
* Revenons à des questions simples : si un accès n'est pas absolument légitime/nécessaire, alors partons du principe que l'isolation est bonne, sans avoir à savoir exactement pourquoi. En cas de bris fonctionnel, le débat pourra être ré-ouvert sur la base, toujours, de la légitimité et des bonnes pratiques.