Pendant des décennies, le C et ses descendants directs ont été les langages de prédilection pour la programmation système. Au début des années 1970, lorsque le C a été développé, il représentait une avancée majeure par rapport au langage assembleur. Cinquante ans plus tard, nous pouvons faire mieux.
En 1970, la sécurité informatique ne préoccupait guère la plupart des gens, et ce fut encore le cas pendant de nombreuses années. La première faille de sécurité majeure sur Internet est apparue bien plus tard, en 1988. Elle était connue sous le nom de « ver Internet » et exploitait un dépassement de tampon, qui se produit lorsqu’un tableau en mémoire est indexé en dehors de ses limites.
Dans la famille des langages C, qui comprend le C++, les limites des tableaux ne sont pas vérifiées. Il incombe au programmeur de s’assurer que l’accès au tableau s’effectue correctement. Les erreurs de dépassement de tampon sont donc fréquentes. Pire encore, il est facile de provoquer délibérément un dépassement de tampon et d’accéder ainsi à des zones de mémoire auxquelles on ne devrait pas avoir accès.
Le dépassement de tampon n’est qu’un exemple de défaut de sûreté de la mémoire. Parmi les autres problèmes connexes figurent l’arithmétique des pointeurs et les pointeurs pendants (également appelés erreurs d’utilisation après libération). Aujourd’hui, de nombreux langages de programmation emploient diverses techniques pour garantir que tout programme écrit dans ces langages sera exempt de problèmes de sûreté de la mémoire. La famille des langages C n’offre aucune garantie de ce type ; la sûreté de la mémoire n’a jamais été un objectif de conception de ces langages.
Environ 70 % des vulnérabilités de sécurité sont dues à des atteintes à la sûreté de la mémoire. Cette affirmation est étayée par une quantité considérable de données. Les problèmes de sûreté de la mémoire représentent :
- 67 % des vulnérabilités exploitées, divulguées et détectées dans la nature (selon l’estimation de Google Project Zero 2021).
- 90 % des vulnérabilités d’Android (selon Google). Bien que ce chiffre ait récemment diminué grâce à l’utilisation de Rust, 89 % des vulnérabilités exploitables à distance restent liées à la sécurité de la mémoire.
- 70 % des vulnérabilités de Microsoft (selon Microsoft).
- La majorité des correctifs récents de vulnérabilités d’Apple (pour Catalina, Big Sur, Monterey, Safari, iOS, tvOS et watchOS).
En juillet 2022, 5/6 des vulnérabilités corrigées dans Chrome 103.0.5060.134 étaient des problèmes de sûreté de la mémoire. Il est évident que l’élimination des failles de sûreté de la mémoire serait extrêmement bénéfique. Le secteur sait depuis de nombreuses années comment y parvenir : utiliser des langages de programmation garantissant la sûreté de la mémoire. Historiquement, le problème a toujours été le coût associé en matière de performances. Compte tenu de l’importance de la sûreté de la mémoire, de nouvelles stratégies ont été élaborées pour l’assurer sans le surcoût habituel. Aujourd’hui, nous savons éliminer les erreurs de sûreté de la mémoire avec un coût à l’exécution faible, voire nul. Des langages tels que Rust s’appuient sur des innovations dans la conception des systèmes de types pour garantir la sûreté de la mémoire sans prise en charge coûteuse à l’exécution.
Cela conduit à une conclusion incontournable : il faut cesser d’écrire du nouveau code système en C/C++ (ou, plus généralement, dans des langages qui ne garantissent pas la sûreté de la mémoire).
Il ne s’agit pas d’un appel à réécrire massivement et sans discernement le code existant. Remplacer des logiciels existants est coûteux et n’est pas sans risque. Toutefois, le secteur doit cesser d’aggraver le problème en ajoutant davantage de code non sûr pour la mémoire aux bases de code existantes. Pour le code existant, il convient de réécrire en priorité les composants les plus sensibles : ceux chargés de valider ou de traiter des entrées utilisateur non fiables, ceux qui s’exécutent dans un contexte privilégié, ceux qui s’exécutent en dehors d’un bac à sable, etc.
Cette position, bien que largement partagée, reste controversée pour certains. Voici quelques-uns des arguments couramment avancés en faveur du statu quo, ainsi que nos réponses à ces arguments.
- Les bugs ne sont pas propres aux langages de programmation.
- La plupart des vulnérabilités résultent de défauts de sécurité de la mémoire. Les langages garantissant la sécurité de la mémoire, tels que Rust, ne peuvent pas présenter ce type de défaut. Par conséquent, l’utilisation d’un langage garantissant la sécurité de la mémoire empêchera d’emblée l’apparition de la plupart des vulnérabilités.
- Les revues de code permettront de détecter les bugs.
- Des études montrent que, même si les revues de code peuvent améliorer les choses, elles passent souvent à côté de nombreux problèmes ; elles ne détectent certainement pas tout.
- Les modules non sécurisés rendent toute la question sans objet.
- Le code non sécurisé est explicitement circonscrit à de très petites sections de code, afin que les ressources puissent être consacrées à sa validation.
- L’implémentation d’un langage garantissant la sécurité de la mémoire peut comporter des bogues.
- En effet, mais les probabilités sont bien plus faibles. Les compilateurs sont relativement petits et soumis à des tests rigoureux. De plus, corriger un compilateur corrigera automatiquement tous les programmes compilés avec celui-ci, contrairement à la correction d’un bogue dans un seul programme.
- Seuls les programmeurs débutants ou incompétents commettent ce genre d’erreurs.
- Au contraire, les données ci-dessus proviennent de grands projets de développement de systèmes, tels que le navigateur Chrome et les systèmes d’exploitation Windows et macOS. Ces projets font appel à certains des développeurs les plus compétents et expérimentés du secteur, et pourtant, ils présentent encore des problèmes de sûreté de la mémoire.
- Ces problèmes peuvent être évités en suivant les bonnes pratiques.
- Voir ci-dessus. Les équipes mentionnées suivent des pratiques très rigoureuses et utilisent les meilleurs outils disponibles.
- Il n’est pas réaliste de réécrire tout le code.
- Personne ne préconise une réécriture complète de l’ensemble du code. Il est plutôt recommandé d’adopter une approche axée sur les éléments clés (privilèges élevés, vaste surface d’attaque, rôle central dans les garanties de sécurité) et d’écrire le nouveau code dans un langage garantissant la sûreté de la mémoire.
- Les performances sont insuffisantes.
- Les performances de Rust sont globalement comparables à celles de C/C++. Des différences mineures ne justifient pas de prendre des risques en matière de sécurité. Dans certaines situations, les programmes Rust peuvent même être plus rapides.
- Les langages de programmation système à mémoire sécurisée comme Rust sont trop récents.
- Rust fait son entrée dans le noyau Linux.
- De grandes parties de navigateurs web comme Firefox sont écrites en Rust.
- Google a ajouté d’énormes quantités de code Rust à Android, sans aucune vulnérabilité.
- Il existe d’autres solutions, telles que l’analyse statique, le fuzzing et le sandboxing.
- La sécurité nécessite une approche à plusieurs niveaux.
- Le sandboxing a ses limites.
- Même les meilleures pratiques modernes en C++ ne peuvent endiguer le flot de vulnérabilités.
Voir « Quantification des problèmes de sécurité de la mémoire et des réactions qu’ils suscitent » pour une analyse détaillée des points ci-dessus.
Malgré les objections, la dynamique en faveur des changements nécessaires s’amplifie. Des investissements importants sont par exemple réalisés dans l’Open Source Software Security Foundation (soutenue par la Linux Foundation). La sécurité de la mémoire a été abordée dans des rapports du Sénat américain ainsi que par la NSA. Consumer Reports s’efforce également de déterminer les différents leviers susceptibles d’accélérer ce mouvement, en formulant une série de recommandations à l’intention des entreprises et des organismes publics.
En résumé :
L’importance de l’informatique pour la société s’est considérablement accrue au cours des cinquante dernières années. Le paysage des menaces pesant sur nos infrastructures informatiques a lui aussi radicalement évolué au cours des dernières décennies. Pourtant, les langages de programmation que nous utilisons pour concevoir nos systèmes informatiques n’ont pas évolué en conséquence. L’absence de sûreté de la mémoire constitue, à elle seule, la principale source de vulnérabilités de sécurité dans les logiciels. Ce problème n’est propre à aucun type de logiciel en particulier : partout où des langages ne garantissant pas la sûreté de la mémoire sont utilisés, les problèmes qui en découlent abondent. Et au vu des chiffres, aucune autre catégorie de vulnérabilités ne s’en approche.
Nous disposons désormais des moyens de remédier à ce problème croissant, et il est essentiel que notre secteur s’y attelle. Heureusement, la prise de conscience progresse, mais la situation est urgente et il n’y a pas de temps à perdre.
À propos de l’auteur
Articles de blog associés

Pourquoi devriez-vous vous intéresser à WebAssembly ?
WebAssembly (Wasm) est un jeu d’instructions binaires portable, rapide et sécurisé, qui permet d’exécuter des applications hautes performances sur n’importe quelle plateforme.
Trois choses à savoir sur les applications d’IA
Les applications d’IA sont des applications modernes, mais elles présentent certaines particularités. Découvrez les points essentiels à connaître sur les applications basées sur l’IA.
État des lieux de la stratégie applicative 2022 : il est temps de moderniser les opérations
Il est devenu évident que, pour maintenir la dynamique de leur transformation numérique, les organisations doivent recentrer leurs efforts sur les fonctions métier. Si les expériences destinées aux clients restent prioritaires, il est également indispensable de permettre la numérisation de fonctions telles que les services juridiques, les ressources humaines et la finance. Les DSI prennent donc les commandes, tandis que la transformation numérique passe de la modernisation des applications à celle des opérations.
Clouds multiples ou multicloud : faciliter la transition
La gestion et la sécurisation des charges de travail deviennent complexes à mesure que les entreprises adoptent une stratégie de cloud connecté. Découvrez comment F5 répond au besoin d’une nouvelle approche de la mise en réseau multicloud.
L’expérience client dépend de la visibilité
Une enquête menée par Dimensional Research auprès de plus de 3 000 utilisateurs d’applications mobiles a confirmé ce que beaucoup d’entre nous pensent des attentes actuelles des clients.
Transformation numérique et explosion du portefeuille d’applications
La transformation numérique stimule la croissance des portefeuilles d’applications et modifie la manière dont celles-ci sont développées, déployées, intégrées et, en définitive, utilisées.