Chrome corrige une vulnérabilité de dépassement de tampon de tas dans WebP
(chromereleases.googleblog.com)- Le déploiement des mises à jour des canaux Chrome Stable et Extended Stable pour desktop inclut un correctif pour une vulnérabilité de dépassement de tampon de tas dans WebP
- Les nouvelles builds sont 116.0.5845.187 sur Mac et Linux, et 116.0.5845.187/.188 sur Windows, avec un déploiement progressif sur plusieurs jours à plusieurs semaines
- Cette release comprend 1 correctif de sécurité, et CVE-2023-4863 est classée Critical
- Apple SEAR et The Citizen Lab de la Munk School de l'Université de Toronto ont signalé cette vulnérabilité le 6 septembre 2023
- Google a indiqué qu'il existe des cas d'exploitation réels, et l'accès aux détails du bug peut être restreint jusqu'à l'application de la version corrigée
Mise à jour des canaux Chrome pour desktop
- Les canaux Stable et Extended Stable ont été mis à jour vers de nouvelles builds pour desktop
- Les versions du canal Stable selon la plateforme sont les suivantes
- Mac : 116.0.5845.187
- Linux : 116.0.5845.187
- Windows : 116.0.5845.187/.188
- Le canal Extended Stable est également déployé avec des versions distinctes
- Windows : 116.0.5845.188
- Mac : 116.0.5845.187
- La mise à jour est déployée progressivement sur plusieurs jours à plusieurs semaines
- La liste complète des changements de cette build est disponible dans le log
Correctif de sécurité : CVE-2023-4863
- Cette release inclut 1 correctif de sécurité
- Le principal correctif apporté par des chercheurs externes concerne la vulnérabilité suivante
- Critical CVE-2023-4863 : dépassement de tampon de tas dans WebP
- Numéro de bug : 1479274
- Auteurs du signalement : Apple Security Engineering and Architecture (SEAR), The Citizen Lab de la Munk School de l'Université de Toronto
- Date du signalement : 6 septembre 2023
- Montant de la récompense : $NA
Exploitation réelle et restriction de la divulgation d'informations
- Google a déclaré qu'un exploit de CVE-2023-4863 existe dans des environnements réels
- L'accès aux détails du bug et aux liens associés peut être restreint jusqu'à ce que la majorité des utilisateurs aient mis à jour vers la version corrigée
- La restriction peut également être maintenue si le même bug se trouve dans une bibliothèque tierce dont dépendent d'autres projets et qui n'a pas encore été corrigée
Détection des bugs de sécurité et canaux de signalement
- De nombreux bugs de sécurité sont détectés avec les outils suivants
- La procédure pour changer de canal de release est expliquée dans le guide des canaux de release Chromium
- Les nouveaux problèmes peuvent être signalés sur crbug.com, et de l'aide est disponible sur le forum d'aide de la communauté Chrome
1 commentaires
Avis sur Hacker News
Dans Google Chrome, les images WebP sont décodées dans le processus de rendu ; même si l’exploitation réussit, elle ne permet donc que l’exécution de code dans le moteur de rendu, à l’intérieur de la sandbox.
Le moteur de rendu est extrêmement complexe et de nombreux exploits y sont découverts chaque année, mais obtenir l’exécution de code dans le moteur de rendu ne donne pas beaucoup plus de droits qu’une page web ordinaire.
En particulier, il n’est pas possible de voir ni de déposer des fichiers sur le système de fichiers local, ni de lire les cookies d’autres domaines.
Ce n’est pas forcément une priorité absolue immédiate, mais s’il n’y a pas déjà un tel exploit en circulation dans la nature, il faut appliquer le correctif dès que possible, à un moment où cela ne crée pas trop de gêne.
Le fait que cela ne soit pas lié à un site ou à un frontend précis en fait plutôt une sorte de XSS renforcé.
Ah, je me suis trompé de fil : je voulais répondre au « jpeg is good enough » de https://news.ycombinator.com/item?id=37479576.
Et même si JavaScript est désactivé, est-ce que le site web ne pourrait pas soudainement quand même exécuter du code ?
Cela me rend donc plus compréhensif envers la lenteur des développeurs de navigateurs à adopter de nouveaux formats.
Les avantages de WebP par rapport à JPEG ne sont pas énormes, essentiellement la transparence, et son succès est resté limité.
Or cela a maintenant entraîné plusieurs failles de sécurité prioritaires, et partout où libwebp est liée, il va falloir diffuser des correctifs pendant le mois à venir.
Je ne dis pas qu’il ne faut rien faire de nouveau, mais je pense que les développeurs ont tendance à sous-estimer assez fortement les coûts.
Il est vrai que l’écosystème WebP est beaucoup moins mûr, mais je suis convaincu qu’il y a aussi eu pas mal de problèmes de sécurité dans le code de traitement de formats plus anciens.
Cela dit, le raisonnement se tient. Il y a encore quelques semaines, l’ambiance chez les internautes était que JPEG XL devait être adopté le plus vite possible et que, pour cela, il suffisait aux développeurs de navigateurs « d’inclure le code du décodeur de référence dans leur base de code », ce qui ne « coûtait presque rien ».
Les autres formats d’image et bibliothèques sont probablement aussi truffés de bugs, mais comme ils ne sont pas utilisés dans des logiciels majeurs, personne ne s’en préoccupe.
Surtout parce que, pour les personnes capables de trouver et d’exploiter ce type de bug, le retour sur investissement en temps est mauvais.
Le simple fait qu’un code soit peu utilisé depuis longtemps ne réduit pas le nombre de bugs.
Si les encodeurs et décodeurs d’images, ainsi que les autres encodeurs/décodeurs, n’utilisaient pas de langages non sûrs, la probabilité de créer ce type de bug serait plus faible.
Indépendamment de cela, je pense que la culture qui consiste à rendre le code plus complexe que nécessaire, ainsi que les développeurs qui ne comprennent pas correctement les détails, posent aussi problème.
Ce correctif est inclus dans Firefox 117.0.1 et Fenix 117.1.0 sortis aujourd’hui : https://hg.mozilla.org/releases/mozilla-release/rev/e245ca21...
À noter que la crate image contient une implémentation de décodeur WebP écrite en Rust sûr : https://github.com/image-rs/image
Elle est longtemps restée assez incomplète, mais de nombreuses fonctionnalités WebP ont été implémentées l’an dernier.
Chromium a désormais une politique qui autorise l’utilisation de dépendances Rust ; Chromium pourrait-il commencer à l’adopter ?
Le commit d’origine à l’origine du problème : https://github.com/webmproject/libwebp/commit/f75dfbf23d1df1...
Le commit qui corrige ce bug : https://github.com/webmproject/libwebp/commit/902bc919033134...
Le commit d’origine optimisait le décodeur de Huffman. Ce décodeur utilise une optimisation bien connue : lire N bits à l’avance, puis déterminer combien de bits il faut réellement consommer et quel symbole décoder. Ou bien, s’il s’agit du préfixe de N bits de plusieurs symboles, déterminer quelle table consulter pour les bits restants
L’ancienne version utilisait une table de correspondance pour les symboles courts, mais les symboles longs nécessitaient de parcourir un graphe. La nouvelle version a amélioré cela en utilisant un tableau de tables de correspondance. Chaque entrée contient
(nbits, value);nbitsest le nombre de bits à consommer etvalueest généralement le symbole. Mais sinbitsdépasse N,valueest interprété comme un index de table, etnbitsest réinterprété comme la longueur du code le plus long dans ce sous-arbre. Chaque table qui suit doit donc contenir2^(nbits - N)entrées. La table racine est toujours fixée à2^NentréesLa nouvelle version calculait le nombre maximal d’entrées (
kTableSize) à partir du nombre de symboles. Évidemment, l’arbre de Huffman provient d’une entrée non fiable, et on peut facilement imaginer des cas oùnbitsdevient très grand. VP8 Lossless autorise concrètement jusqu’à 15 bits ; si toutes les LUT sont chacune mappées vers une table auxiliaire distincte, la table maximale possible atteint2^N + 2^15entrées. Il ne faut pas non plus tant de symboles que cela pour la construire :16-Nsymboles par table suffisentFait intéressant, le code lui-même avait un mode qui ne faisait que calculer la taille de la table (appel de
VP8LBuildHuffmanTableavecroot_table == NULL), mais, pour une raison quelconque, il n’était pas utilisé et supposait une taille maximale fixe. Donc, en construisant un arbre de Huffman de manière à maximiser le nombre d’entrées, on écrivait au-delà de la zone allouéeOn comprend pourquoi c’est arrivé. L’étape de décodage de Huffman est l’une des parties les plus coûteuses en calcul dans de nombreux formats de compression, donc même de petites améliorations comptent. L’optimisation ci-dessus est bien connue, mais les chemins de codes longs sont généralement considérés comme rares et donc peu prioritaires à optimiser. Le message du commit d’origine réfutait cette hypothèse, ce qui a permis son merge. Il est difficile d’affirmer qu’un langage à sûreté mémoire aurait empêché ce problème. C’est un cas rare où l’on peut être tenté d’éviter activement les vérifications de dépassement
[1] Cela dit, la corruption mémoire se produit pendant la construction de la table, pas dans une boucle serrée ; des vérifications partielles de dépassement auraient donc beaucoup aidé. Le correctif réel n’a pas modifié du tout la fonction
ReadSymbol. Malgré tout, la sûreté des boucles serrées doit être justifiée, et une mauvaise justification peut tout faire échouerSi l’affirmation selon laquelle les vérifications de limites ne sont pas nécessaires est correcte, très bien. WUFFS n’émet pas de vérifications de limites à l’exécution
Mais si, comme ici, le logiciel sort de ses limites et se trompe, il ne compilerait pas avec WUFFS
On pourrait penser : « c’est impossible », et si WUFFS était un langage de programmation généraliste, ce serait vrai. D’après le théorème de Rice, toute propriété sémantique non triviale est indécidable
Heureusement, WUFFS n’est pas un langage généraliste. La plupart des logiciels ne peuvent pas être écrits en WUFFS, mais les codecs d’image, oui
Je me demande toutefois s’il aurait été possible de créer des tests automatisés capables de repérer ce genre de problème
Dans le code que je manipule personnellement, on peut extraire certains calculs dans des fonctions séparées pour les tester indépendamment. Ici, cela aurait peut-être été difficile pour des raisons de performance, mais je n’en suis pas sûr
Correction de l’écriture hors limites dans
BuildHuffmanTablehttps://github.com/webmproject/libwebp/commit/902bc919033134...
Cela pourrait signifier que Google, après avoir trouvé ce bug, a optimisé le fuzzer pour libwebp et trouve donc davantage de bugs
Cela semble avoir été signalé par Apple, et ressemble beaucoup à cette mise à jour de sécurité : https://support.apple.com/en-us/HT213906
Cela paraît donc assez probable. Apple utilise peut-être libwebp en interne dans ImageIO, ou a pu faire une erreur similaire
Les codecs d’image ont une longue histoire de vulnérabilités
Le traitement d’image proprement dit peut être du code linéaire assez propre pour être écrit même en FORTRAN IV avec sûreté mémoire, mais dès que la compression entre en jeu, il y a beaucoup de structures de données à longueur variable, de suivi de pointeurs, etc.
À cela s’ajoute la pression pour que l’exécution soit rapide
Est-ce que cela affecte aussi Electron ? Si oui, quelles versions ?
Ce qui est intéressant, c’est que Signal Desktop, qui utilise Electron en interne, s’exécute sous Linux sans sandbox [1][2]
[0] https://github.com/electron/electron/pull/39824
[1] https://github.com/signalapp/Signal-Desktop/issues/5195
[2] https://github.com/signalapp/Signal-Desktop/pull/4381
Existe-t-il une voie d’exploitation réaliste pour ça ?
D’après ce que j’ai entendu, sur 64 bits, le heap spraying n’est plus vraiment praticable
Y a-t-il en mémoire un objet prévisible qui puisse être écrasé ?
Même en 64 bits, le heap spraying est clairement encore utilisé dans les exploits noyau. Je ne sais pas trop quelles primitives les gens utilisent dans les exploits V8