Ces dernières années, la multiplication des réglementations en cybersécurité, qu’elles soient émises par des gouvernements ou des organismes de certification privés, a fait de la qualité et de la sécurité du code des enjeux cruciaux pour les éditeurs de logiciels et les fabricants de produits. Pour répondre à ces nouvelles exigences et démontrer leur conformité, l’analyse statique de code s’impose comme une technique incontournable dans les outils de vérification. Un nombre croissant de normes en matière de sûreté et de cybersécurité en impose l’usage, notamment dans les systèmes critiques.
Cependant, malgré son adoption croissante, l’analyse statique reste parfois mal comprise ou mal utilisée. Il est donc essentiel d’en clarifier les principes, les capacités réelles, les limites et les bonnes pratiques d’intégration dans le cycle de développement logiciel.
Cet article propose une vue d’ensemble technique des fondements, des méthodes et des cas d’usage industriels des outils d’analyse statique appliqués à la détection de défauts dans le code source.
Définition et périmètre de l’analyse statique
L’analyse statique des logiciels regroupe un ensemble de technologies générales visant à comprendre le comportement d’une application cible sans l’exécuter. Elle peut être appliquée pour :
effectuer des transformations (traduction, optimisation, compilation, parallélisation…) ;
détecter des défauts au niveau du code source ou du code binaire.
Les compilateurs constituent une classe bien connue d’outils d’analyse statique (SA), utilisés quotidiennement. Ils combinent plusieurs objectifs d’analyse :
- la détection d’instructions mal formées dans l’application,
- la traduction des instructions du langage de programmation en instructions de bas niveau (langage machine),
- l’optimisation du code pour réduire la taille et le temps d’exécution du programme généré.
La technologie d’analyse statique couvre un spectre allant de l’analyse textuelle (recherche de mots-clés ou de motifs), à l’analyse syntaxique (où la syntaxe du langage source est connue), jusqu’à l’analyse sémantique (où la syntaxe et la sémantique du langage de programmation sont maîtrisées). Les algorithmes SA peuvent être appliqués au niveau d’une procédure ou de manière inter-procédurale via le graphe d’appels. Parmi les algorithmes couramment utilisés dans les outils SA, on retrouve l’analyse de flux de contrôle, de flux de données, de flux d’information, l’analyse d’alias, l’interprétation abstraite, les chaînes use-def, l’analyse de contamination, etc.
Un outil SA qui ne produirait que des vrais positifs et des vrais négatifs serait un outil parfait. Aucun outil n’atteint ce niveau de précision : les outils SA sémantiques produisent des résultats classés en vrais positifs et vrais négatifs, mais également des faux positifs (ils ne manquent aucun défaut présent dans l’application, mais génèrent des messages superflus), tandis que les outils SA non sémantiques produisent des vrais positifs et vrais négatifs, mais aussi des faux négatifs (ils peuvent manquer des défauts présents dans l’application, mais ne génèrent pas de messages erronés).
La technologie SA permet la détection de nombreux types de défauts, allant de la qualité logicielle à la sûreté et à la cybersécurité. Le niveau de formalisation varie selon le type de défaut : par exemple, les erreurs d’exécution (RTE) sont parfaitement formalisées par les normes du langage de programmation (comportements indéfinis, non spécifiés ou définis par l’implémentation), alors que les violations de règles de codage ou les failles de cybersécurité ne disposent pas d’une telle formalisation. Le niveau de formalisation détermine l’exhaustivité de l’outil correspondant : les outils SA exhaustifs peuvent, avec une technologie adaptée, détecter “toutes” les occurrences des défauts formalisés qu’ils ciblent (comme les RTE), alors qu’il est impossible de prouver qu’ils détectent toutes les occurrences des défauts non formalisés.
Chaque outil SA cible un sous-ensemble de défauts connus, appelé périmètre de détection. En général, deux outils SA différents ne couvrent pas exactement le même périmètre, bien que leurs périmètres puissent se recouper. Même lorsqu’ils traitent le même défaut, ils peuvent détecter des occurrences plus ou moins complexes de celui-ci, selon les technologies utilisées. En conséquence, il est difficile de choisir l’outil SA le plus efficace pour une classe d’applications donnée.
Pourquoi et comment utiliser les outils d’analyse statique ?
De plus en plus de normes de sûreté ou de cybersécurité identifient l’analyse statique comme un moyen de vérification requis pour les logiciels critiques.
Par conséquent, l’utilisation d’un outil d’Analyse Statique devient obligatoire dans un nombre croissant de processus de développement industriel, même si les normes ne prescrivent ni outil spécifique ni objectifs de SA. Les industriels sont alors responsables de :
définir les défauts cibles qui mettent en risque leur application,
sélectionner, parmi plus de 200 outils existants, celui qui couvre les défauts visés,
- configurer l’outil SA choisi pour détecter ces défauts,
- lancer l’analyse statique et produire la liste des résultats,
- produire le rapport de vérification.
Contrairement à une analyse manuelle, l’analyse réalisée par un outil d’Analyse Statique est parfaitement réplicable de manière identique et sans effort.
Il est facile de relancer l’analyse d’une version à l’autre d’une application, et même d’analyser les différences entre les résultats obtenus sur deux versions successives.
À noter : la bonne réalisation des cinq étapes implique des compétences issues de plusieurs domaines.
- Etape 1 : Connaissance des exigences de vérification normatives et des risques en sûreté ou cybersécurité associés à l’application critique dans son contexte d’exécution.
- Etape 2 et 3 : Maîtrise de base des technologies SA et des outils d’analyse statique, afin de sélectionner l’outil adapté aux objectifs de vérification, et de configurer correctement cet outil pour détecter les défauts visés.
- Etape 4 : Compréhension du comportement de l’outil SA sélectionné, pour vérifier que les résultats produits sont conformes aux objectifs de vérification.
- Etape 5 : Connaissance des objectifs de vérification, de la configuration de l’outil, et capacité à classifier les résultats en vrai/faux positifs et vrai/faux négatifs.
Les trois premières étapes forment une phase préparatoire qui doit être réalisée une seule fois. Cette phase peut être menée pour une application industrielle ou un ensemble d’applications afin de configurer l’outil d’analyse statique sélectionné, en incluant si nécessaire la criticité des défauts.
La plupart des outils SA offrent la possibilité de contourner certaines vérifications en ajoutant des annotations dans le code source. Le rapport de la phase préparatoire inclut la justification de tous les choix effectués à ce stade, ainsi que des recommandations d’usage de l’outil Analyse Statique, et se conclut par une procédure de vérification. Les deux dernières étapes constituent la phase d’exécution, qui doit être appliquée à chaque nouvelle version de chaque application. À partir de la procédure issue de la phase préparatoire, chaque nouvelle version peut être analysée de manière cohérente. Le rapport de vérification doit contenir non seulement les résultats fournis par l’outil SA, mais aussi les défauts résiduels justifiés et les annotations présentes dans le code source.
Il convient de noter que, dans certains contextes industriels, un outil d’analyse statique est déjà utilisé sur les applications pour couvrir d’autres objectifs de vérification.
Dans ce cas, la deuxième étape consiste à identifier le sous-ensemble des objectifs de vérification définis lors de la première étape qui doivent être couverts par cet outil. La troisième étape consiste soit à définir une configuration spécifique permettant de couvrir ces objectifs, soit à fusionner cette configuration avec celle par défaut.
Cette démarche doit être étudiée avec soin afin d’éviter non seulement des surcoûts pendant la phase d’exécution (étapes quatre et cinq), mais aussi un rejet de l’outil par les équipes de développement ou de vérification.
La phase préparatoire est souvent difficile à anticiper d’un point de vue industriel, car les éditeurs encouragent l’utilisation des outils d’analyse statique dans leur configuration par défaut. Cependant, quinze années d’utilisation de l’analyse statique dans divers contextes industriels ont démontré que cette stratégie échoue fréquemment : les défauts critiques ne sont pas détectés avant la mise en service de l’application, et les équipes de développement et de vérification considèrent que les résultats de l’analyse sont inutiles. Cette phase préparatoire est pourtant le seul moyen d’identifier les défauts réellement critiques et d’augmenter concrètement la sécurité des applications critiques. En général, l’industrie fait appel à des compétences externes pour faciliter cette étape. Le rapport de préparation doit justifier l’identification des défauts, le choix et la configuration de l’outil SA, ainsi que toute recommandation nécessaire (annotations, pragmas, etc.) pour atteindre les objectifs de vérification.
Conclusion
Lorsqu’elle est correctement préparée, configurée et intégrée dans un processus documenté et outillé, l’analyse statique constitue un levier puissant pour améliorer la sûreté et la cybersécurité des logiciels critiques. Il ne s’agit pas simplement d’utiliser un outil avec ses paramètres par défaut : cela exige une réflexion approfondie sur les objectifs de vérification, les périmètres de détection pertinents et le contexte d’application. L’expérience a montré que la phase préparatoire est souvent la clé d’un usage efficace et accepté par les équipes projet.
En résumé, l’analyse statique ne remplace pas l’expertise humaine, elle la complète intelligemment pour atteindre un objectif commun : maîtriser les risques logiciels dès les premières lignes de code.