Les navigateurs font confiance au code qui analyse des fichiers multimédias créés par des inconnus, et les attaquants ont à maintes reprises exploité ces formats contre les bogues mémoire des décodeurs. Mozilla sponsorisait Rust depuis près de sept ans, un langage conçu comme une alternative sûre au C++, mais à la mi-2016, aucun de ses composants n'était livré dans Firefox ; le langage axé sur la sûreté devait encore faire ses preuves au sein d'un navigateur C++ géant et critique en termes de performances.

Les moyens évidents de protéger les utilisateurs étaient tous insuffisants. Corriger l'analyseur C++ signifiait défendre chaque nouvelle vulnérabilité pour toujours ; l'isoler en bac à sable réduisait le rayon d'impact sans éliminer la classe de bogues ; et réécrire tout le navigateur en Rust était un pari pluriannuel qui casserait le produit en cours de route. L'équipe Media Playback de Mozilla a plutôt choisi un élément délimité et critique pour la sécurité : l'analyseur de métadonnées mp4 qui traite des médias web non fiables.

Ralph Giles et Matthew Gregan ont écrit un remplacement entièrement en Rust pour cet analyseur, l'ont exposé via une API C afin que la compilation C++ environnante reste intacte, et ont vérifié qu'il produisait des résultats identiques au code qu'il remplaçait. Firefox 48 l'a ensuite embarqué sur toutes les plateformes de bureau, plaçant pour la première fois du Rust de production devant des centaines de millions d'utilisateurs, avec la prise en charge d'Android prévue ensuite.

Le pilote a fonctionné parce qu'il a transformé une idéologie en preuve. Les règles de compilation de Rust ont éliminé la classe de bogues mémoire pour ce composant au lieu d'ajouter une couche de défense supplémentaire, et la télémétrie de Firefox a enregistré zéro problème sur plus d'un milliard d'utilisations du nouveau code. Mozilla l'a qualifié de première étape, non d'aboutissement : un modèle éprouvé — remplacer le composant délimité le plus risqué, prouver la parité, livrer et mesurer — pour la migration plus vaste à venir.

Commencer la migration par l'analyseur qui ingère des données non fiables

L'analyse de médias est le point où des octets non fiables rencontrent du code natif, c'est pourquoi le pilote a ciblé le plus grand risque restant par ligne

Un analyseur autonome a une frontière nette et testable : une sortie identique à celle du composant C++ pouvait être vérifiée

La sûreté mémoire à la compilation a éliminé toute la classe de bogues plutôt que d'ajouter une autre couche de défense

Zéro problème de télémétrie sur un milliard d'utilisations a transformé un pari sur un langage en preuve de production mesurable

Exposer Rust via une API C a permis de livrer l'analyseur sans perturber le reste de la compilation C++

Introduire une nouvelle technologie dans une base de code existante est une greffe, non une réécriture : choisir le composant le plus risqué doté d'une frontière testable, le livrer, et laisser les données de production plaider pour aller plus loin

Firefox 48 a apporté le premier Rust de production à tous les utilisateurs de bureau, et Mozilla a considéré ce jalon comme un coup d'ouverture plutôt qu'un aboutissement : le wiki Oxidation cartographiait quelles fonctionnalités Rust arriveraient sur chaque plateforme et quand, et le Bugzilla 1284816 suivait la transformation de Rust en partie obligatoire de la compilation de Firefox. Un plantage par manque de mémoire découvert pendant le déploiement a été corrigé pour Firefox 48 en passant à une API de construction de threads pouvant échouer, qui renvoie une erreur au lieu de planter. La même voie — des remplacements délimités à sûreté mémoire prouvés par la télémétrie — est devenue le modèle des composants Rust qui ont suivi.

VÉRIFIEZ LES SOURCES

Les sources

  1. Shipping Rust in Firefox Mozilla Hacks · hacks.mozilla.org ·
  2. mozilla/mp4parse-rust — Parser for ISO Base Media Format aka video/mp4 written in Rust GitHub · github.com