Vous subissez une attaque ? Faire appel à notre réponse aux incidents

info@angelforce.eu
Développement sécurisé

Feuille de route de sécurité mémoire pour C et C++ sans tout réécrire

Comment les équipes produit réduisent le risque mémoire en C et C++ ce trimestre : inventaire, isolation, fuzzing et courte liste de réécriture.

Aussi en :EnglishTürkçeDeutschEspañolItalianoPolskiNederlandsEesti

Illustration : Feuille de route de sécurité mémoire pour C et C++ sans tout réécrire

Une feuille de route de sécurité mémoire est un plan avec des responsables et des échéances, et vous pouvez en rédiger une ce trimestre sans toucher à la majeure partie de votre code C et C++. La réécriture viendra plus tard et ne portera que sur les parties qui la justifient. Ce qu'il vous faut dès maintenant : une vision claire de l'endroit où se trouve le code non sûr, un moyen de le contenir et une trace de ce que vous avez décidé.

Le document de la CISA, The Case for Memory Safe Roadmaps, décrit comment les éditeurs de logiciels peuvent migrer vers des langages à sécurité mémoire (MSL) afin d'éliminer les vulnérabilités liées à la mémoire. Il demande aux éditeurs de publier des feuilles de route pour que leurs clients voient comment ils assument la responsabilité des résultats en matière de sécurité, pratiquent la transparence radicale et adoptent une approche descendante. Ce sont des principes du Secure by Design, et le document s'adresse autant aux dirigeants qu'aux ingénieurs. Ce second public compte : une feuille de route sans sponsor finit oubliée dans un wiki.

Ce que couvrent les sources, et ce qu'elles ne couvrent pas

La page de synthèse de la CISA ne mentionne que la transition vers les MSL ainsi que la création et la publication d'une feuille de route. Elle ne montre pas le contenu complet du document ; nous n'affirmons donc rien sur ce qu'il dit du fuzzing ou de l'isolation de processus. Ces deux étapes ci-dessous relèvent de notre pratique, pour les années qui séparent « nous avons du C++ aujourd'hui » de « nous avons un langage plus sûr dans les parties qui comptent ». Considérez-les comme des mesures provisoires, pas comme un substitut à la feuille de route.

Les sources ne donnent pas non plus de chiffres sur le risque que chaque étape permet d'éliminer. Nous n'en inventerons pas. Mesurez-le vous-même, à partir de l'historique de vos plantages et de vos vulnérabilités.

Étape 1 : inventorier le code non sûr

On ne peut pas prioriser ce que l'on n'a pas listé. Construisez un tableau par composant, et non par dépôt, car un même dépôt mélange souvent un utilitaire sans risque et un parseur réseau.

ChampPourquoi c'est important
Langage et standardIndique ce qui peut ou non être migré
Accessible de l'extérieur ?Réseau, fichier, USB, liaison série, canal de mise à jour
Traite des entrées non fiables ?Détermine la priorité du fuzzing et de la réécriture
S'exécute avec quels privilèges ?Détermine l'utilité de l'isolation
Tiers ou interne ?Détermine qui peut corriger
Responsable et dernière modification substantielleLe code mort peut souvent être supprimé

Incluez les bibliothèques embarquées (vendored) et les composants de firmware. Les équipes matérielles, en particulier, ont souvent du vieux code C dans les bootloaders, les drivers et les gestionnaires de mise à jour que personne n'a ouverts depuis des années. Ces composants méritent une ligne.

Étape 2 : isoler ce que vous ne pouvez pas encore remplacer

Pour chaque composant marqué comme accessible et traitant des entrées non fiables, demandez-vous ce qui se passe s'il est entièrement compromis. Si la réponse est « tout », c'est votre premier changement d'architecture. Déplacez le parseur dans son propre processus, retirez-lui ses privilèges et supprimez son accès aux fichiers, aux sockets et aux clés dont il n'a pas besoin.

Cela ne corrige pas le bug. Cela limite ce qu'il vaut pour un attaquant. C'est cohérent avec l'objectif du Secure Software Development Framework (SP 800-218) du NIST : atténuer l'impact potentiel de l'exploitation de vulnérabilités que vous n'avez pas encore trouvées.

Étape 3 : soumettre les points d'entrée au fuzzing

Prenez dans votre inventaire les composants qui traitent des entrées non fiables et écrivez un harnais de fuzzing pour chacun. Exécutez ces harnais dans la CI avec un budget de temps, et conservez le corpus de plantages. Commencez par les formats de fichiers, les messages de protocole et les paquets de mise à jour, puisque ce sont les chemins qu'un tiers peut atteindre.

Compilez les binaires de fuzzing avec la détection d'erreurs mémoire du compilateur activée, afin qu'une lecture hors limites silencieuse devienne un échec visible. Chaque plantage que vous analysez vous apporte ce dont la feuille de route a besoin : des preuves indiquant quels composants méritent une réécriture. Si un harnais ne trouve rien après des exécutions prolongées, c'est utile aussi : vous pouvez classer ce composant plus bas.

Étape 4 : choisir une courte liste de réécriture

Servez-vous des trois premières étapes pour choisir les candidats. Une bonne première réécriture présente ces propriétés :

  • Elle traite des entrées non fiables.
  • Elle a une interface étroite, ce qui permet de la remplacer derrière la même API.
  • Elle a produit des plantages lors du fuzzing ou possède un historique de bugs.
  • Elle est assez petite pour qu'une seule équipe la termine en une ou deux itérations de livraison.

Laissez en C ou C++ le code stable, interne et non exposé, et dites-le dans la feuille de route. Écrire « non planifié, isolé, fuzzé » à côté d'un composant est honnête, et vos clients savent en tirer parti. C'est notre interprétation de la transparence radicale : vous exposez votre position, et toutes les lignes n'ont pas à se terminer par une réécriture. La synthèse de la CISA nomme ce principe mais ne dit pas ce qu'il implique pour les composants qui restent en C ou C++.

Les nouveaux composants sont l'endroit le moins coûteux pour commencer. Décidez dès maintenant quel langage sera utilisé pour tout nouveau code exposé au réseau, et inscrivez-le dans vos standards d'ingénierie.

Étape 5 : formaliser par écrit et l'intégrer à votre processus

Le NIST décrit le SSDF comme un socle de pratiques de haut niveau à intégrer dans le cycle de développement que vous utilisez déjà, dans le but de traiter les causes racines pour que les vulnérabilités ne réapparaissent pas. Intégrez vos règles de sécurité mémoire à ce processus existant : choix du langage pour le nouveau code, fuzzing dans la CI, point de contrôle en revue pour les constructions non sûres. Le SSDF offre aussi aux acheteurs et aux fournisseurs un vocabulaire commun, ce qui aide lorsque le questionnaire de sécurité d'un client aborde la sécurité mémoire.

Pour les listes de contrôle de codage, le projet OWASP Secure Coding Practices Quick Reference Guide est archivé. Ses listes ont été reprises dans l'OWASP Developer Guide ; utilisez cette version plutôt qu'un PDF périmé.

Par où commencer

  1. Exportez la liste de tous les composants C et C++, y compris le code embarqué (vendored) et le firmware, puis remplissez le tableau d'inventaire ci-dessus. Limitez-vous à deux semaines.
  2. Repérez les composants qui lisent des entrées non fiables et listez ce à quoi chacun peut accéder s'il est compromis.
  3. Placez les trois composants exposés les plus critiques dans des processus séparés à faibles privilèges, ou planifiez la modification avec un responsable nommé.
  4. Écrivez des harnais de fuzzing pour ces mêmes composants et exécutez-les dans la CI. Passez les plantages en revue chaque semaine.
  5. Choisissez un composant à réécrire dans un langage à sécurité mémoire, et fixez une règle de langage pour tout nouveau code exposé au réseau.
  6. Publiez en interne une feuille de route d'une page avec responsables et échéances, puis décidez de ce que vous partagez avec vos clients. Si vous souhaitez un regard extérieur, notre service de développement logiciel sécurisé et nos tests d'intrusion peuvent examiner l'inventaire et tester les composants isolés.

Comment nous pouvons vous aider

Développement sécurisé

Nous intégrons la sécurité aux logiciels dès le premier commit, et nous développons nos propres outils de sécurité.

Nous contacter
Équipe AngelForce

Rédigé par l’équipe AngelForce : des consultants en sécurité certifiés CEH, LPT Master et CISA qui testent, surveillent et protègent les systèmes d’organisations dans toute l’Europe et en Turquie.

Rédigé avec l’aide de l’IA à partir des sources publiques indiquées sur cette page, puis relu par l’équipe AngelForce avant publication.

Sources

  1. www.cisa.gov/resources-tools/resources/case-memory-safe-roadmaps
  2. csrc.nist.gov/pubs/sp/800/218/final
  3. owasp.org/projects/secure-coding-practices-quick-reference-guide

Articles : Développement sécurisé

Dites-nous ce que vous devez protéger

Décrivez votre environnement et vos objectifs. Nous vous répondrons par e-mail.

Nous contacter
info@angelforce.eu

AngelForce OÜ · Tallinn, Estonie