Rejoignez-nous le 30 avril : dévoilement de Parasoft C/C++test CT pour l'excellence en matière de tests continus et de conformité | En savoir plus

Qu’est-ce que le CERT C++ ?

Portrait de Miroslaw Zielinski, directeur de la gestion des produits chez Parasoft
27 octobre 2023
7 min lire

Le développement de logiciels inclut la sécurité comme élément clé et CERT C++ est l'une des meilleures options si vous souhaitez suivre les normes de codage de sécurité appropriées. Lisez la suite pour voir pourquoi vous ne devriez pas ignorer le CERT C++.

La sécurité devient un nouveau mantra pour les équipes de développement de logiciels, en particulier pour les responsables de la sécurité ou des logiciels critiques. Dans le passé, la sécurité était souvent une fonctionnalité que les équipes essayaient d'ajouter aux systèmes déjà construits à la toute fin du cycle de développement, souvent en tournant dans des cercles vicieux de tests d'intrusion et de corrections. Aujourd’hui, nous savons que la sécurité est une discipline d’ingénierie solide soutenue par de multiples programmes et normes de recherche.

Si vous souhaitez que votre système soit sécurisé dès la conception, vous devez commencer dès le début du processus de développement et vous assurer que chaque ligne de code créée suit les meilleures pratiques de sécurité. Pour les équipes qui développent en C++, l’une des meilleures options sur laquelle s’appuyer est la Norme de codage sécurisé CERT. Parasoft C/C++test est le seul outil qui prend entièrement en charge cette norme. Tests de sécurité de Parasoft et la conformité est la solution la plus complète du marché pour le code C et C++.

Qu’est-ce que le CERT C++ ?

La norme SEI CERT C++, publiée pour la première fois en 2006, est une extension de la norme CERT C. Tous deux viennent du Équipe d'intervention d'urgence informatique (CERT) du Software Engineering Institute de l'Université Carnegie Mellon.

L'objectif principal du CERT C++ est de promouvoir des pratiques de codage sécurisées en fournissant aux développeurs un sous-ensemble plus sûr du langage C++ qui évite les faiblesses logicielles conduisant à des vulnérabilités de sécurité. De plus, ces règles et pratiques de codage contribuent à améliorer la fiabilité et la maintenabilité du logiciel. La norme CERT C++ est souvent utilisée comme norme de codage pour aider les organisations à atteindre leurs objectifs de conformité en matière de sûreté et de sécurité.

Le rôle de « cstdint » dans CERT C++

Avant C++11, l'absence ou la séparation de la standardisation des types entiers en C++ a amené certains développeurs à utiliser le langage C. fichier pour les définitions de types. Cela a provoqué des problèmes de compatibilité dans le codage, la construction de programmes portables et l'intégration avec les fonctionnalités C++. en C++ est un outil précieux car il offre des types entiers de taille précise, améliorant la portabilité du code et réduisant les risques de problèmes de sécurité liés aux entiers. Néanmoins, il est important de noter que le simple fait d'utiliser n'élimine pas automatiquement les vulnérabilités, telles que les dépassements d'entiers, la confusion des types, les dépassements de tampon, les vulnérabilités de chaîne de format et les problèmes big/small endian qui peuvent conduire à des vulnérabilités dans l'interprétation des données.

Pour maintenir une base de code sécurisée, vous devez adhérer aux meilleures pratiques de codage CERT C++ établies, telles que la vérification minutieuse des limites, le choix des types d'entiers appropriés et la validation des données d'entrée. Ces précautions sont cruciales pour réduire la probabilité de problèmes de sécurité.

Expressions primaires en C++

Les expressions primaires en C++ sont les éléments constitutifs du langage et englobent les variables, les littéraux, les appels de fonction, etc. Dans le contexte du codage sécurisé avec CERT C++, les expressions primaires sont au centre de l'attention car ces opérations peuvent être des sources potentielles de vulnérabilités. La norme de codage fournit des règles et des lignes directrices pour utiliser les expressions primaires en toute sécurité, telles que :

  • Éviter les variables non initialisées pour éviter un comportement indéfini.
  • Utiliser des types de données appropriés et des conversions de types sécurisées pour éviter les vulnérabilités liées aux données.
  • Assurez-vous que les appels de fonction sont effectués avec une gestion des erreurs et une validation des paramètres appropriées pour éviter des problèmes tels que des débordements de tampon.
  • Gérer correctement les pointeurs et les références pour éviter les vulnérabilités liées à la mémoire.

Directives de codage CERT C++

La norme SEI CERT C++ introduit un ensemble de règles pour appliquer des pratiques de codage sécurisées et éliminer les constructions de code vulnérables. La norme est organisée en 11 chapitres qui contiennent des règles dans des domaines spécifiques. Contrairement au CERT C, la norme de codage CERT C++ ne comporte que des règles et aucune recommandation. Ils sont en attente d'un examen et d'un développement plus approfondis.

SEI CERT C++ s'appuie sur la norme CERT C et englobe le sous-ensemble de règles CERT C qui s'appliquent au C++. À l'heure actuelle (gardez à l'esprit que le CERT est un standard de vie), il existe 143 règles CERT C++ et 136 règles héritées du CERT C. Un aperçu de la norme CERT C++ est présenté dans le tableau suivant suivi d'une liste de ses chapitres.

Graphique montrant le nombre de règles CERT C++ par chapitre, à la fois les règles CERT C++ originales et celles héritées du CERT C.

Règle 01. Déclarations et initialisation (DCL)

Fournit des règles et des directives pour déclarer et initialiser des variables et des objets de manière à garantir un état initialisé valide et à éviter les pièges courants.

Règle 02. Expressions (EXP)

Couvre les règles liées aux expressions, en soulignant la nécessité d'une gestion appropriée des résultats des expressions, en évitant les effets secondaires involontaires et en garantissant que les expressions sont bien formées et maintenables.

Règle 03. Entiers (INT)

Se concentre sur les règles de gestion des nombres entiers en mettant l'accent sur la prévention des dépassements d'entiers, des dépassements inférieurs et d'autres problèmes liés aux opérations sur les nombres entiers.

Règle 04. Conteneurs (CTR)

Ce chapitre traite des règles d'utilisation des conteneurs de bibliothèque standard C++ tels que les vecteurs et les tableaux, favorisant une gestion et une utilisation sûres et efficaces des conteneurs.

Règle 05. Caractères et chaînes (STR)

Fournit des lignes directrices pour la gestion appropriée des caractères et des chaînes, notamment en garantissant une terminaison nulle appropriée et en évitant les vulnérabilités courantes liées aux chaînes.

Règle 06. Gestion de la mémoire (MEM)

Se concentre sur les règles permettant une gestion efficace de la mémoire, notamment l'allocation et la désallocation dynamiques de la mémoire, afin d'éviter les fuites de mémoire et d'autres problèmes liés à la mémoire.

Règle 07. Entrée Sortie (FIO)

Couvre les règles pour des opérations d'entrée et de sortie sécurisées, en soulignant l'importance de valider les données d'entrée et de gérer les opérations sur les fichiers en toute sécurité.

Règle 08. Exceptions et gestion des erreurs (ERR)

Traite les règles de gestion des exceptions et des erreurs, en mettant l'accent sur les meilleures pratiques de gestion des exceptions et des erreurs dans le code C++.

Règle 09. Programmation orientée objet (POO)

Fournit des lignes directrices pour la programmation orientée objet, notamment des recommandations pour la conception des classes, l'héritage et le polymorphisme.

Règle 10. Concurrence (CON)

Se concentre sur les règles liées à la programmation simultanée, à la résolution des problèmes et aux meilleures pratiques en matière de multithreading et de parallélisme.

Règle 49. Divers (MSC)

Contient diverses règles qui ne rentrent pas parfaitement dans les autres catégories mais qui sont importantes pour écrire de manière sécurisée et fiable Code C++.

Comme l'illustre le tableau ci-dessus, chacune de ces règles de niveau supérieur contient des règles plus spécifiques dont certaines sont spécifiques au C++ et d'autres du CERT C s'appliquent également.

Parasoft C / C ++test prend entièrement en charge les directives de codage CERT C++. La configuration de test (« Règles SEI CERT C++ ») active tous les vérificateurs de l'ensemble de règles CERT C++ d'origine et ceux du CERT C applicables au C++, ce qui est précisément tel que le CERT le définit pour assurer la sécurité de votre base de code C++. Les organisations développant avec C et C++, y compris les équipes qui envisagent de passer au C++, peuvent s'appuyer sur une solution unique avec des rapports cohérents.

Les équipes bénéficient également de rapports de conformité dédiés aux CERT C et C++, pour construire un processus de conformité durable. Grâce aux extensions de reporting, les utilisateurs peuvent obtenir une vue dynamique du processus de conformité et examiner les violations priorisées selon le cadre d'évaluation des risques CERT.

Le CERT attribue à chaque violation un score pour les trois facteurs suivants:

  • Gravité
  • Probabilité
  • Coût de la correction

La priorité est calculée comme le produit de ces trois facteurs et divisée en niveaux : L1, L2 et L3. L1 représente des violations de haute gravité avec une probabilité élevée et un faible coût de remédiation. Ce sont ceux que les équipes souhaitent le plus résoudre, car ils indiquent des problèmes graves qui ne sont pas compliqués à résoudre. L'utilisation du cadre de notation du CERT fournit une aide précieuse pour concentrer les efforts et permettre aux équipes de tirer le meilleur parti des budgets temps.

En plus des widgets, des explorateurs de violations et d'un cadre de notation des risques qui vous aide à vous orienter rapidement dans l'avancement du processus de conformité, le cadre de reporting de Parasoft vous fait également gagner du temps en générant automatiquement des rapports de conformité adaptés aux audits de code. Il s'agit d'une fonctionnalité intéressante si votre organisation est plus formelle dans le processus de développement.

Bénéficiez du CERT C++

C++ est un excellent langage. Bien qu'il possède de nombreuses fonctionnalités du langage OO moderne, lui permettant de concevoir des systèmes complexes avec des modèles de conception OO avancés, il offre également une grande efficacité car il vous permet d'accéder à la mémoire directement via des pointeurs sans vérifier si cet accès est correct.

Bien entendu, ces avantages ont un prix. Avec C++, même les développeurs de logiciels très expérimentés peuvent créer du code vulnérable, le plus souvent en raison de problèmes d'accès à la mémoire et de gestion. Les dépassements de tampon, l'utilisation de références en suspens et les dépassements d'entiers peuvent tous conduire à un comportement indéfini, qui peut être exploité de plusieurs manières.

Un exemple est l’injection d’arc. Un attaquant peut tenter de transférer de manière malveillante le contrôle du code existant dans la mémoire du processus de manière non prévue.

Un autre exemple est l'injection de code, qui consiste à injecter du code dans la mémoire du système en cours d'exécution pour prendre le contrôle d'un système doté des privilèges du programme compromis, ou pire encore, d'un niveau d'accès au noyau. Une fois ce contrôle pris, les pertes peuvent être dévastatrices.

Comment pouvons-nous empêcher les attaquants de pénétrer dans notre système ? Il n'est pas possible de prendre une base de code existante et d'essayer de deviner toutes les failles de sécurité possibles. La meilleure option actuellement disponible pour les programmeurs C/C++ est de créer en premier lieu du code exempt de certaines constructions qui se sont avérées être une source de failles de sécurité.

Regardons une illustration simple. L'extrait de code source ci-dessous est directement tiré du standard CERT C++ (règle EXP61-CPP).

auto g() {
int i = 12;
return [&] {
i = 100; // Problem
return i;
};
}

void f() {
int j = g()();
}

Dans cet exemple, la fonction g() renvoie un lambda, qui capture implicitement la variable locale automatique « i » par référence. Ce code mal écrit présente au moins une vulnérabilité de sécurité lorsque lambda est renvoyée par l'appel g(). La référence capturée fera référence à une variable dont la durée de vie est terminée (la fonction g a disparu).

Par conséquent, lorsque le lambda est exécuté dans f(), l'utilisation de la référence pendante dans le lambda affecte un comportement indéfini. Ce comportement non défini peut être exploité pour prendre le contrôle du programme. La mémoire qui était occupée par « i » pendant la durée de vie de la fonction g est déjà libérée, et ce morceau de la pile est probablement déjà réutilisé à d'autres fins, éventuellement une adresse de retour de l'appel de fonction, qui, une fois écrasée, peut être utilisée pour exécuter du code arbitraire.

Cette vulnérabilité spécifique est détectable par la règle, EXP61-CPP Un objet lambda ne doit survivre à aucun de ses objets de référence capturés. Le code source conforme à CERT C++ ne doit contenir aucune occurrence de ce problème.

CERT C++ inclut de nombreuses autres règles qui peuvent détecter des problèmes potentiels et vous aideront à promouvoir des pratiques de codage sécurisées. L'utilisation de CERT C++ offre des avantages significatifs aux développeurs de logiciels.

  • Améliore la sécurité. Le respect de la norme permet d'obtenir un code plus sécurisé, réduisant ainsi les vulnérabilités et le risque de failles de sécurité.
  • Améliore la fiabilité. Il promeut les meilleures pratiques qui améliorent la fiabilité et la robustesse du code, réduisant ainsi la probabilité de défauts et de pannes.
  • Maintenabilité. Les règles encouragent un code plus facile à comprendre et à maintenir, simplifiant ainsi les efforts de développement et de maintenance en cours.
  • Conformité. La norme aide les organisations et les développeurs à respecter les normes de sécurité et de sûreté, les réglementations et les exigences spécifiques au secteur.
  • Réduit le débogage et les tests. En évitant les pièges de codage courants, les développeurs peuvent consacrer moins de temps au débogage et aux tests et plus de temps au développement productif.
  • Une concurrence plus sûre. La norme comprend des lignes directrices pour une programmation simultanée sécurisée (multi-processus et multithread), réduisant le risque de conditions de concurrence critique et de problèmes liés aux threads.
  • Sensibilisation à la sécurité. Les développeurs deviennent plus soucieux de la sécurité et apprennent à identifier et atténuer de manière proactive les risques de sécurité dans leur code.

Les directives de codage de sécurité, lorsqu'elles sont utilisées de manière cohérente, peuvent contribuer à renforcer votre code source et constituent la stratégie la plus efficace pour assurer la sécurité globale du système. De nos jours, il est vraiment difficile de trouver une justification pour ne pas suivre une norme de codage de sécurité telle que CERT C++.

Comment accélérer la conformité MISRA C & SEI CERT C