Contacts

Méthode de vérification de code statique. Analyse du code hérité lorsque le code source est perdu : faire ou ne pas faire ? Combiner la séquence d'actions de différents types d'analyse dans l'environnement de développement

introduction

Les fonctionnalités standard des produits logiciels et des divers systèmes de contrôle sont insuffisantes pour la plupart des clients. Les systèmes de gestion de sites Web (par exemple, WordPress, Joomla ou Bitrix), les programmes de comptabilité, les systèmes de gestion des clients (CRM), l'entreprise et la production (par exemple, 1C et SAP) offrent de nombreuses possibilités d'étendre les fonctionnalités et de s'adapter aux besoins de clients spécifiques. Ces opportunités sont mises en œuvre à l'aide de modules tiers, sur mesure ou de personnalisation de ceux existants. Ces modules sont des codes de programme écrits dans l'un des langages de programmation intégrés qui interagissent avec le système et implémentent les fonctionnalités requises par les clients.

Toutes les organisations ne réalisent pas qu'un code intégrable sur mesure ou un site Web peut contenir de graves vulnérabilités, dont l'exploitation par un attaquant peut entraîner la fuite d'informations confidentielles, et les onglets de programme sont des sections spéciales de code conçues pour effectuer toute opération sur des commandes secrètes. connu du développeur de code. . De plus, le code personnalisé peut contenir des bogues susceptibles de détruire ou de corrompre des bases de données ou de perturber des processus métier bien établis.

Les entreprises qui connaissent les risques décrits ci-dessus essaient d'impliquer des auditeurs et des spécialistes de l'analyse du code source du programme dans l'acceptation des modules prêts à l'emploi, afin que les experts déterminent la sécurité de la solution développée et s'assurent qu'ils ne contiennent pas de vulnérabilités, d'erreurs, ou des onglets de programme. Mais cette méthode de contrôle présente un certain nombre d'inconvénients. Tout d'abord, ce service augmente sérieusement le budget de développement ; deuxièmement, l'audit et l'analyse prennent beaucoup de temps - d'une semaine à plusieurs mois ; et troisièmement, cette approche ne garantit pas l'absence totale de problèmes avec le code analysé - il existe une possibilité d'erreur humaine et de détection de vecteurs d'attaque précédemment inconnus après que le code a été accepté et a commencé à fonctionner.

Il existe une méthodologie de développement sécurisée qui prévoit l'intégration des processus d'audit et de contrôle de code au stade de la création d'un produit logiciel - SDL (Security Development Lifecycle, cycle de vie de développement sécurisé). Cependant, seul un développeur de logiciels peut appliquer cette méthodologie, si nous parlons de clients, alors SDL n'est pas applicable pour eux, car le processus implique la restructuration des algorithmes de génération de code et il est trop tard pour l'utiliser dès l'acceptation. De plus, de nombreux développements affectent une petite partie du code existant, auquel cas le SDL n'est pas non plus applicable.

Pour résoudre le problème de l'audit du code source et fournir une protection contre l'exploitation des vulnérabilités dans les codes embarqués et les applications Web, il existe des analyseurs de code source.

Classification des analyseurs de code source

Les analyseurs de code source sont une classe de produits logiciels conçus pour détecter et empêcher l'exploitation d'erreurs logicielles dans les codes source. Tous les produits destinés à l'analyse du code source peuvent être conditionnellement divisés en trois types :

  • Le premier groupe comprend des analyseurs de code d'application Web et des outils pour empêcher l'exploitation des vulnérabilités du site Web.
  • Le deuxième groupe est constitué d'analyseurs de code intégrables qui vous permettent de détecter les problèmes dans le code source des modules conçus pour étendre les fonctionnalités des systèmes d'entreprise et de production. Ces modules comprennent des programmes pour la gamme de produits 1C, des extensions de systèmes CRM, des systèmes de gestion d'entreprise et des systèmes SAP.
  • Le dernier groupe est destiné à l'analyse du code source dans divers langages de programmation qui ne sont pas liés aux applications métier et aux applications Web. Ces analyseurs sont destinés aux clients et aux développeurs de logiciels. En particulier, ce groupe d'analyseurs est utilisé pour utiliser la méthodologie de développement de logiciels sécurisés. Les analyseurs de code statique détectent les problèmes et les vulnérabilités potentielles dans les codes sources et fournissent des recommandations pour les résoudre.

Il convient de noter que la plupart des analyseurs sont de types mixtes et remplissent les fonctions d'analyse d'une large gamme de produits logiciels - applications Web, code embarqué et logiciels conventionnels. Cependant, dans cette revue, l'accent est mis sur l'utilisation d'analyseurs par les clients de développement, donc une plus grande attention est accordée aux applications Web et aux analyseurs de code embarqués.

Les analyseurs peuvent contenir divers mécanismes d'analyse, mais le plus courant et le plus universel est l'analyse statique du code source - SAST (Static Application Security Testing), il existe également des méthodes d'analyse dynamique - DAST (Dynamic Application Security Testing), qui vérifient le code pendant son exécution, et diverses options hybrides qui combinent différents types d'analyses. L'analyse dynamique est une méthode de vérification autonome qui peut étendre les capacités de l'analyse statique ou être utilisée indépendamment dans les cas où l'accès aux codes sources n'est pas disponible. Dans cette revue, seuls les analyseurs statiques sont pris en compte.

Les analyseurs de code embarqués et les analyseurs d'applications Web diffèrent par leur ensemble de caractéristiques. Cela inclut non seulement la qualité de l'analyse et la liste des produits logiciels et langages de programmation pris en charge, mais également des mécanismes supplémentaires : la possibilité d'effectuer une correction automatique des erreurs, la disponibilité de fonctions pour empêcher l'exploitation des erreurs sans modification du code, la possibilité de mettre à jour la base de données intégrée des vulnérabilités et des erreurs de programmation, la disponibilité des certificats de conformité et la capacité à répondre aux exigences des différents régulateurs.

Comment fonctionnent les analyseurs de code source

Les principes généraux de fonctionnement sont similaires pour toutes les classes d'analyseurs : à la fois les analyseurs de code source d'applications Web et les analyseurs de code intégrables. La différence entre ces types de produits réside uniquement dans la capacité à déterminer les caractéristiques d'exécution du code et d'interaction avec le monde extérieur, ce qui se reflète dans les bases de données de vulnérabilité de l'analyseur. La plupart des analyseurs du marché remplissent les fonctions des deux classes, vérifiant aussi bien le code intégré dans les applications métier que le code des applications Web.

Les données d'entrée pour l'analyseur de code source sont un tableau de codes source de programme et ses dépendances (modules chargeables, logiciels tiers utilisés, etc.). À la suite des travaux, tous les analyseurs publient un rapport sur les vulnérabilités détectées et les erreurs de programmation. De plus, certains analyseurs fournissent des fonctions de correction automatique des erreurs.

Il convient de noter que la correction automatique des erreurs ne fonctionne pas toujours correctement, cette fonctionnalité est donc destinée uniquement aux développeurs d'applications Web et de modules embarqués, le client du produit doit se fier uniquement au rapport final de l'analyseur et utiliser les données reçues pour prendre une décision sur l'acceptation et la mise en œuvre du code développé ou l'envoyer pour révision.

Figure 1. Algorithme de l'analyseur de code source

Lors de l'évaluation du code source, les analyseurs utilisent diverses bases de données contenant des descriptions de vulnérabilités et d'erreurs de programmation :

  • Propre base de données de vulnérabilités et d'erreurs de programmation - chaque développeur d'analyseurs de code source possède ses propres départements d'analyse et de recherche, qui préparent des bases de données spécialisées pour l'analyse des codes source des programmes. La qualité de votre propre base de données est l'un des critères clés qui affecte la qualité globale du produit. De plus, votre propre base de données doit être dynamique et constamment mise à jour - les nouveaux vecteurs d'attaque et l'exploitation des vulnérabilités, ainsi que les changements dans les langages de programmation et les méthodes de développement, obligent les développeurs d'analyseurs à constamment mettre à jour la base de données pour maintenir des contrôles de haute qualité. Les produits à base statique non actualisable perdent le plus souvent dans les tests comparatifs.
  • Bases de données nationales d'erreurs de programmation - il existe un certain nombre de bases de données nationales de vulnérabilités, qui sont compilées et maintenues par les régulateurs dans différents pays. Par exemple, aux États-Unis, la base CWE est utilisée - Common Weakness Enumeration, qui est maintenue par l'organisation MITRE, qui est soutenue, entre autres, par le département américain de la Défense. La Russie ne dispose pas encore d'une base de données similaire, mais le FSTEC de Russie prévoit à l'avenir de compléter ses bases de données de vulnérabilités et de menaces par une base de données d'erreurs de programmation. Les analyseurs de vulnérabilité implémentent la prise en charge de la base de données CWE en l'intégrant dans leur propre base de données de vulnérabilité ou en l'utilisant comme mécanisme de vérification distinct.
  • Exigences et recommandations des normes pour la programmation sécurisée - il existe à la fois un certain nombre de normes gouvernementales et industrielles qui décrivent les exigences pour le développement d'applications sécurisées, ainsi qu'un certain nombre de recommandations et de "meilleures pratiques" d'experts mondiaux dans le domaine du développement et de la protection des logiciels . Ces documents ne décrivent pas directement les erreurs de programmation, contrairement à CWE, mais contiennent une liste de méthodes qui peuvent être converties pour être utilisées dans un analyseur de code source statique.

La qualité de l'analyse, le nombre de faux positifs et d'erreurs manquées dépendent directement des bases utilisées dans l'analyseur. De plus, l'analyse de conformité aux exigences des régulateurs permet de faciliter et de simplifier la procédure d'audit externe de l'infrastructure et du système d'information dans le cas où les exigences sont obligatoires. Par exemple, les exigences PCI DSS sont obligatoires pour les applications Web et le code intégré qui fonctionne avec les informations de paiement par carte bancaire, tandis qu'un audit externe de conformité PCI DSS est effectué, y compris une analyse des produits logiciels utilisés.

Marché mondial

Il existe de nombreux analyseurs différents sur le marché mondial - à la fois de fournisseurs bien connus dans le domaine de la sécurité et d'acteurs de niche traitant uniquement de cette classe de produits. Le Gartner Analytical Center classe et évalue les analyseurs de code source depuis plus de cinq ans, tandis que jusqu'en 2011, Gartner a distingué les analyseurs statiques discutés dans cet article séparément, les combinant plus tard dans une classe supérieure - les outils de test de sécurité des applications (Application Security Testing) . ).

Dans le Gartner Magic Quadrant en 2015, HP, Veracode et IBM sont les leaders du marché des tests de sécurité. Dans le même temps, Veracode est la seule des principales entreprises à ne pas disposer d'un analyseur en tant que produit logiciel, et la fonctionnalité n'est fournie qu'en tant que service dans le cloud Veracode. Les autres entreprises leaders proposent soit exclusivement des produits qui effectuent des vérifications sur les ordinateurs des utilisateurs, soit la possibilité de choisir entre un produit et un service cloud. HP et IBM restent les leaders mondiaux du marché au cours des cinq dernières années, un aperçu de leurs produits est donné ci-dessous. Le produit de Checkmarx, qui se spécialise uniquement dans cette classe de produits, est le plus proche des positions de leader, il est donc également inclus dans l'examen.

Figure 2. Magic Quadrant des analystesGartner par les acteurs du marché de l'analyse de la sécurité des applications en août 2015

Selon le rapport d'analyse de ReportsnReports, aux États-Unis, la taille du marché des analyseurs de code source en 2014 s'élevait à 2,5 milliards de dollars. D'ici 2019, il devrait doubler sa croissance pour atteindre 5 milliards de dollars avec une croissance annuelle de 14,9 %. Plus de 50 % des organisations interrogées pour ce rapport prévoient d'allouer et d'augmenter les budgets pour l'analyse du code source dans le développement personnalisé, et seulement 3 % ont parlé négativement de l'utilisation de ces produits.

Le grand nombre de produits dans la zone des challengers confirme la popularité de cette classe de produits et le développement rapide de l'industrie. Au cours des cinq dernières années, le nombre total de fabricants dans ce quadrant a presque triplé et trois produits ont été ajoutés par rapport au rapport de 2014.

Marché russe

Le marché russe des analyseurs de code source est assez jeune - les premiers produits publics ont commencé à apparaître sur le marché il y a moins de cinq ans. Dans le même temps, le marché s'est formé dans deux directions - d'une part, les entreprises développant des produits à tester pour identifier les capacités non déclarées dans les laboratoires du FSTEC, du FSB et du ministère de la Défense de la Fédération de Russie; d'autre part, les entreprises impliquées dans divers domaines de la sécurité ont décidé d'ajouter une nouvelle classe de produits à leur portefeuille.

Les acteurs les plus notables du nouveau marché sont Positive Technologies, InfoWatch et Solar Security. Positive Technologies est spécialisée depuis longtemps dans la recherche et l'analyse de vulnérabilités ; leur portefeuille comprend le produit MaxPatrol, l'un des leaders du marché national du contrôle de sécurité externe, il n'est donc pas surprenant que l'entreprise ait décidé de faire une analyse interne et de développer son propre analyseur de code source. InfoWatch s'est développé en tant que développeur de systèmes DLP, se transformant finalement en un groupe d'entreprises à la recherche de nouvelles niches de marché. Appercut a rejoint InfoWatch en 2012, ajoutant un outil d'analyse de code source au portefeuille InfoWatch. Les investissements et l'expérience d'InfoWatch ont permis de développer rapidement le produit à un niveau élevé. Solar Security n'a officiellement présenté son produit Solar inCode qu'à la fin du mois d'octobre 2015, mais déjà au moment de sa sortie, il disposait de quatre implémentations officielles en Russie.

Les entreprises qui développent des analyseurs de code source pour les tests de certification depuis des décennies ne sont généralement pas pressées d'offrir des analyseurs pour les entreprises, donc notre examen ne contient qu'un seul produit de ce type - d'Echelon. Peut-être, à l'avenir, pourra-t-il évincer d'autres acteurs du marché, principalement grâce à la grande expérience théorique et pratique des développeurs de ce produit dans le domaine de la recherche de vulnérabilités et de fonctionnalités non déclarées.

Un autre acteur de niche sur le marché russe est Digital Security, une société de conseil en sécurité de l'information. Ayant une vaste expérience dans la réalisation d'audits et la mise en œuvre de systèmes ERP, elle a trouvé un créneau vide et s'est lancée dans le développement d'un produit d'analyse de la sécurité des systèmes ERP, qui, entre autres fonctions, contient des mécanismes d'analyse des codes sources pour les programmes embarqués.

Bref aperçu des analyseurs

Le premier outil d'analyse de code source de notre revue est un produit de Fortify, propriété de Hewlett-Packard depuis 2010. La gamme HP Fortify comprend divers produits d'analyse des codes de programme : il existe également le service Fortify On-Demand SaaS, qui consiste à télécharger le code source sur le cloud HP, et l'application complète HP Fortify Static Code Analyzer installée sur l'infrastructure du client.

HP Fortify Static Code Analyzer prend en charge une large gamme de langages de programmation et de plates-formes, y compris des applications Web écrites en PHP, Python, Java/JSP, ASP.Net et JavaScript, et du code intégrable dans ABAP (SAP), Action Script et VBScript.

Figure 3. Interface de l'analyseur de code statique HP Fortify

Parmi les fonctionnalités du produit, il convient de souligner la présence dans HP Fortify Static Code Analyzer de la prise en charge de l'intégration avec divers systèmes de gestion de développement et du suivi des erreurs. Si le développeur de code fournit au client un accès direct aux rapports de bogues à Bugzilla, HP Quality Center ou Microsoft TFS, l'analyseur peut générer automatiquement des rapports de bogues sur ces systèmes sans avoir besoin d'étapes manuelles.

Le fonctionnement du produit est basé sur les propres bases de connaissances de HP Fortify, formées en adaptant la base CWE. Le produit met en œuvre une analyse pour répondre aux exigences des recommandations DISA STIG, FISMA, PCI DSS et OWASP.

Parmi les lacunes de HP Fortify Static Code Analyzer, il convient de noter le manque de localisation du produit pour le marché russe - l'interface et les rapports sont en anglais, le manque de matériel et de documentation pour le produit en russe, l'analyse des Le code pour 1C et d'autres produits nationaux au niveau de l'entreprise n'est pas pris en charge.

Avantages de l'analyseur de code statique HP Fortify :

  • marque bien connue, solution de haute qualité;
  • une grande liste de langages de programmation analysés et d'environnements de développement pris en charge ;
  • la capacité d'intégration avec les systèmes de gestion de développement et d'autres produits HP Fortify ;
  • soutien aux normes, recommandations et « meilleures pratiques » internationales.

Checkmarx CxSAST est un outil de la société américano-israélienne Checkmarx, spécialisée dans le développement d'analyseurs de code source. Ce produit est principalement destiné à l'analyse de logiciels conventionnels, mais grâce à la prise en charge des langages de programmation PHP, Python, JavaScript, Perl et Ruby, il est idéal pour l'analyse d'applications Web. Checkmarx CxSAST est un analyseur universel qui n'a pas de spécificité prononcée et peut donc être utilisé à n'importe quelle étape du cycle de vie du produit logiciel - du développement à l'application.

Figure 4. Interface Checkmarx CxSAST

Checkmarx CxSAST implémente la prise en charge de la base d'erreurs de code de programme CWE, les contrôles de conformité OWASP et SANS 25, les normes PCI DSS, HIPAA, MISRA, FISMA et BSIMM sont pris en charge. Tous les problèmes détectés par Checkmarx CxSAST sont classés par gravité, allant de mineur à critique. L'une des caractéristiques du produit est la présence de fonctions de visualisation de code avec la construction d'organigrammes de voies d'exécution et de recommandations pour corriger les problèmes de liaison à un schéma graphique.

Les inconvénients du produit incluent le manque de prise en charge de l'analyse du code intégré dans les applications métier, le manque de localisation et la difficulté d'utilisation du produit pour les clients du code de programme, car la solution est principalement destinée aux développeurs et est étroitement intégrée aux environnements de développement. .

Avantages de Checkmarx CxSAST :

  • un grand nombre de langages de programmation pris en charge ;
  • grande vitesse du produit, possibilité de scanner uniquement des sections nominales du code;
  • la possibilité de visualiser des graphiques d'exécution du code analysé ;
  • des rapports visuels et des métriques de code source conçues graphiquement.

Un autre produit d'un fournisseur bien connu est l'analyseur de code IBM Security AppScan Source. La gamme AppScan comprend de nombreux produits liés au développement de logiciels sécurisés, mais d'autres produits ne conviendront pas à l'utilisation du code logiciel par les clients, car ils comportent de nombreuses fonctionnalités inutiles. IBM Security AppScan Source, comme Checkmarx CxSAST, est principalement conçu pour les organisations de développeurs, tout en prenant en charge encore moins de langages de développement Web - uniquement PHP, Perl et JavaScript. Les langages de programmation pour le code intégré dans les applications métier ne sont pas pris en charge.

Figure 5. Interface source d'IBM Security AppScan

IBM Security AppScan Source est étroitement intégré à la plate-forme de développement IBM Rational, de sorte que le produit est le plus souvent utilisé pendant la phase de développement et de test des produits logiciels et n'est pas bien adapté pour l'acceptation ou la vérification d'une application personnalisée.

Une caractéristique d'IBM Security AppScan Source est qu'il prend en charge l'analyse de programme pour IBM Worklight, une plate-forme pour les applications professionnelles mobiles. La liste des normes et exigences prises en charge est clairsemée - Recommandations PCI DSS et DISA et OWASP, la base de données de vulnérabilité compare les problèmes trouvés avec CWE.

Aucun avantage particulier de cette solution pour les clients en développement n'a été identifié.

AppChecker de la société nationale CJSC NPO Echelon est une solution apparue sur le marché assez récemment. La première version du produit est sortie il y a seulement un an, mais l'expérience d'Echelon en analyse de code est à prendre en compte. "NPO Echelon" est un laboratoire d'essais du FSTEC, du FSB et du ministère de la Défense de la Fédération de Russie et possède une vaste expérience dans le domaine de l'analyse statique et dynamique des codes sources des programmes.

Figure 6. Interface "Echelon" AppChecker

AppChecker est conçu pour analyser une variété de logiciels et d'applications Web écrits en PHP, Java et C/C++. Prend entièrement en charge la classification des vulnérabilités CWE et prend en compte les recommandations OWASP, CERT et NISP. Le produit peut être utilisé pour effectuer un audit de conformité aux exigences PCI DSS et à la norme IBBS-2.6-2014 de la Banque de Russie.

Les inconvénients du produit sont dus au stade précoce de développement de la solution - il n'y a pas suffisamment de support pour les langages de développement Web populaires et la capacité d'analyser le code intégré.

Avantages :

  • la possibilité de réaliser un audit selon les exigences nationales et PCI DSS ;
  • prise en compte de l'influence des fonctionnalités des langages de programmation en raison de la configuration flexible des projets analysés ;
  • à bas prix.

PT Application Inspector est un produit du développeur russe Positive Technologies, qui se distingue par son approche pour résoudre le problème de l'analyse du code source. PT Application Inspector vise principalement à trouver des vulnérabilités dans le code, et non à identifier les erreurs logicielles courantes.

Contrairement à tous les autres produits de cette revue, PT Application Inspector a non seulement la capacité de signaler et de démontrer les vulnérabilités, mais également la capacité de créer automatiquement des exploits pour certaines catégories et types de vulnérabilités - de petits modules exécutables qui exploitent les vulnérabilités trouvées. A l'aide des exploits créés, il est possible en pratique de vérifier le danger des vulnérabilités trouvées, ainsi que de contrôler le développeur en vérifiant le fonctionnement de l'exploit après la fermeture déclarée de la vulnérabilité.

Figure 7. Interface de l'inspecteur d'application PT

PT Application Inspector prend en charge à la fois les langages de développement d'applications Web (PHP, JavaScript) et le code intégré pour les applications métier - SAP ABAP, SAP Java, Oracle EBS Java, Oracle EBS PL/SQL. En outre, le produit PT Application Inspector prend en charge la visualisation des itinéraires d'exécution des programmes.

PT Application Inspector est une solution unique pour les développeurs et les clients exécutant des applications Web personnalisées et des plug-ins d'application métier. La base de données des vulnérabilités et des erreurs dans le code du programme contient les propres développements de Positive Technologies, la base de données CWE et WASC (Web Consortium Vulnerability Database, un analogue de CWE pour les applications Web).

L'utilisation de PT Application Inspector vous permet de répondre aux exigences de PCI DSS, STO BR IBBS, ainsi qu'à l'ordre 17 du FSTEC et à l'exigence d'absence de capacités non déclarées (pertinent pour la certification du code).

Avantages :

  • prise en charge de l'analyse des applications Web et d'un vaste ensemble de systèmes de développement pour les applications métier ;
  • produit local localisé ;
  • un large éventail de normes d'État prises en charge ;
  • en utilisant la base de données de vulnérabilités des applications Web WASC et le classificateur CWE ;
  • la possibilité de visualiser le code du programme et de rechercher des signets de programme.

InfoWatch Appercut a été développé par la société russe InfoWatch. La principale différence entre ce produit et tous les autres de cette collection est sa spécialisation dans la fourniture d'un service aux clients d'applications métier.

InfoWatch Appercut prend en charge presque tous les langages de programmation qui créent des applications Web (JavaScript, Python, PHP, Ruby) et des plug-ins pour les offres commerciales - 1C, ABAP, X++ (ERP Microsoft Axapta), Java, Lotus Script. InfoWatch Appercut a la capacité de s'adapter aux spécificités d'une application particulière et au caractère unique des processus métier de chaque entreprise.

Figure 8. Interface InfoWatch Appercut

InfoWatch Appercut prend en charge de nombreuses exigences pour une programmation efficace et sécurisée, y compris les exigences générales PCI DSS et HIPPA, les recommandations CERT et OWAST et les "meilleures pratiques", ainsi que les recommandations des fabricants de plateformes de processus métier - 1C, SAP, Oracle, Microsoft.

Avantages :

  • produit national localisé certifié par le FSTEC de Russie ;
  • le seul produit prenant en charge toutes les plates-formes commerciales populaires en Russie, notamment 1C, SAP, Oracle EBS, IBM Collaboration Solutions (Lotus) et Microsoft Axapta ;
  • un scanner rapide qui effectue des vérifications en quelques secondes et est capable de vérifier uniquement le code modifié et les extraits de code.

Digital Security ERPScan est un produit spécialisé pour l'analyse et la surveillance de la sécurité des systèmes d'entreprise construits sur des produits SAP, la première version est sortie en 2010. En plus du module de configuration, de vulnérabilité et de contrôle d'accès (SOD), ERPScan comprend un module d'évaluation de la sécurité du code source qui implémente les fonctions de recherche de signets, d'appels critiques, de vulnérabilités et d'erreurs de programmation dans le code dans les langages de programmation ABAP et Java. Dans le même temps, le produit prend en compte les spécificités de la plateforme SAP, corrèle les vulnérabilités détectées dans le code avec les paramètres de configuration et les droits d'accès, et effectue une meilleure analyse que les produits non spécialisés qui fonctionnent avec les mêmes langages de programmation.

Figure 9 Interface ERPScan de sécurité numérique

Les fonctionnalités supplémentaires d'ERPScan incluent la possibilité de générer automatiquement des correctifs pour les vulnérabilités détectées, ainsi que de générer des signatures pour d'éventuelles attaques et de télécharger ces signatures vers des systèmes de détection et de prévention des intrusions (en partenariat avec CISCO). De plus, le système contient des mécanismes d'évaluation des performances du code intégré, ce qui est essentiel pour les applications métier, car le fonctionnement lent de modules supplémentaires peut sérieusement affecter les processus métier d'une organisation. Le système prend également en charge l'analyse conformément aux recommandations spécifiques pour l'analyse de code d'application métier, telles que EAS-SEC et BIZEC, ainsi qu'aux recommandations générales PCI DSS et OWASP.

Avantages :

  • spécialisation approfondie sur une plate-forme d'applications métier avec corrélation d'analyse avec les paramètres de configuration et les droits d'accès ;
  • tests de performances du code embarqué ;
  • création automatique de correctifs pour les vulnérabilités trouvées et les correctifs virtuels ;
  • rechercher les vulnérabilités zero-day.

Solar inCode est un outil d'analyse de code statique conçu pour détecter les vulnérabilités de la sécurité des informations et les fonctionnalités non déclarées dans le code source des logiciels. La principale caractéristique distinctive du produit est la possibilité de restaurer le code source des applications à partir d'un fichier de travail en utilisant la technologie de décompilation (ingénierie inverse).

Solar inCode vous permet d'analyser le code source écrit dans les langages de programmation Java, Scala, Java pour Android, PHP et Objective C. Contrairement à la plupart des concurrents, la liste des langages de programmation pris en charge comprend des outils de développement pour les plateformes mobiles Android et iOS.

Figure 10Interface

Dans les cas où le code source n'est pas disponible, Solar inCode permet l'analyse des applications finies, cette fonctionnalité prend en charge les applications Web et les applications mobiles. Notamment, pour les applications mobiles, il suffit de copier simplement le lien vers l'application depuis Google Play ou Apple Store dans le scanner, l'application sera automatiquement téléchargée, décompilée et vérifiée.

L'utilisation de Solar inCode vous permet de répondre aux exigences de PCI DSS, STO BR IBBS, ainsi qu'à l'ordre 17 du FSTEC et à l'exigence d'absence de capacités non déclarées (pertinent pour la certification du code).

Avantages :

  • Prise en charge de l'analyse des applications pour les appareils mobiles fonctionnant sous Android et iOS ;
  • prend en charge l'analyse des applications Web et des applications mobiles sans utiliser le code source des programmes ;
  • donne les résultats de l'analyse sous la forme de recommandations spécifiques pour éliminer les vulnérabilités ;
  • génère des recommandations détaillées pour la mise en place d'outils de protection : SIEM, WAF, FW, NGFW ;
  • facilement intégré dans le processus de développement logiciel sécurisé en prenant en charge le travail avec les référentiels de code source.

conclusions

La présence de bogues logiciels, de vulnérabilités et de signets dans les logiciels développés sur mesure, qu'il s'agisse d'applications Web ou de plug-ins pour applications métier, constitue un risque sérieux pour la sécurité des données de l'entreprise. L'utilisation d'analyseurs de code source vous permet de réduire considérablement ces risques et de contrôler la qualité du travail effectué par les développeurs de code sans avoir besoin de temps et d'argent supplémentaires consacrés aux services d'experts et d'auditeurs externes. Dans le même temps, l'utilisation d'analyseurs de code source, le plus souvent, ne nécessite pas de formation spéciale, l'affectation d'employés individuels et n'introduit pas d'autres inconvénients si le produit n'est utilisé que pour l'acceptation et que le développeur effectue la correction des erreurs. Tout cela rend cet outil obligatoire pour une utilisation lors de l'utilisation de développements personnalisés.

Lors du choix d'un analyseur de code source, il faut partir de la fonctionnalité des produits et de la qualité de leur travail. Tout d'abord, vous devez faire attention à la capacité du produit à effectuer des vérifications pour les langages de programmation dans lesquels les codes sources vérifiés sont implémentés. Le critère suivant dans le choix d'un produit devrait être la qualité du test, qui peut être déterminée par la compétence de la société de développement et lors de l'opération de démonstration du produit. Un autre facteur de choix d'un produit peut être la possibilité d'auditer la conformité aux exigences des normes nationales et internationales, si leur mise en œuvre est requise pour les processus commerciaux de l'entreprise.

Dans cette revue, le leader incontesté parmi les produits étrangers en termes de prise en charge du langage de programmation et de qualité de numérisation est la solution HP Fortify Static Code Analyzer. Checkmarx CxSAST est également un bon produit, mais il ne peut analyser que les applications régulières et les applications Web, il n'y a pas de prise en charge des plug-ins pour les applications métier dans le produit. La solution IBM Security AppScan Source semble pâle par rapport à ses concurrents et ne diffère ni en fonctionnalité ni en qualité des contrôles. Cependant, ce produit n'est pas destiné aux utilisateurs professionnels et est destiné à être utilisé dans les sociétés de développement, où il peut montrer une plus grande efficacité que ses concurrents.

Parmi les produits russes, il est difficile de distinguer un leader incontesté, le marché est représenté par trois produits principaux - InfoWatch Appercut, PT Application Inspector et Solar inCode. Dans le même temps, ces produits diffèrent considérablement sur le plan technologique et sont conçus pour différents publics cibles - le premier prend en charge davantage de plates-formes d'applications métier et se caractérise par une vitesse élevée en raison de la recherche de vulnérabilités à l'aide de méthodes d'analyse exclusivement statiques. La seconde combine l'analyse statique et dynamique, ainsi que leur combinaison, ce qui, en plus d'améliorer la qualité de l'analyse, entraîne une augmentation du temps de vérification du code source. Le troisième vise à résoudre les problèmes des utilisateurs professionnels et des spécialistes de la sécurité de l'information, et vous permet également de vérifier les applications sans accès au code source.

L '«échelon» d'AppChecker n'est pas encore à la hauteur de la concurrence et dispose d'un petit ensemble de fonctionnalités, mais étant donné le stade précoce de développement du produit, il est tout à fait possible que dans un avenir proche, il revendique les premières places dans les classements du code source. analyseurs.

Digital Security ERPScan est un excellent produit pour résoudre la tâche hautement spécialisée d'analyse des applications métier pour la plate-forme SAP. Se concentrant uniquement sur ce marché, Digital Security a développé un produit unique dans sa fonctionnalité, qui non seulement analyse le code source, mais prend également en compte toutes les spécificités de la plateforme SAP, les paramètres de configuration spécifiques et les droits d'accès aux applications métiers, et a également la capacité de créer automatiquement des corrections aux vulnérabilités découvertes.


annotation

L'analyse statique est un moyen de vérifier l'exactitude du code source d'un programme. Le processus d'analyse statique comprend trois étapes. Tout d'abord, le code analysé est divisé en lexèmes - constantes, identifiants, etc. Cette opération est effectuée par le lexer. Les jetons sont ensuite transmis à l'analyseur, qui construit une arborescence de code basée sur ces jetons. Enfin, une analyse statique de l'arbre construit est effectuée. Cet article de présentation décrit trois méthodes d'analyse statique : l'analyse de parcours d'arbre de code, l'analyse de flux de données et l'analyse de flux de données avec sélection de chemin.

introduction

Les tests sont une partie importante du processus de développement d'applications. Il existe de nombreux types de tests différents, dont deux types liés au code de programme : l'analyse statique et l'analyse dynamique.

L'analyse dynamique est effectuée sur le code exécutable du programme compilé. Dans ce cas, seul le comportement spécifique à l'utilisateur est vérifié, c'est-à-dire uniquement le code qui est exécuté pendant le test. L'analyseur dynamique peut trouver des fuites de mémoire, mesurer les performances du programme, obtenir la pile d'appels, etc.

L'analyse statique permet de vérifier le code source d'un programme avant son exécution. En particulier, tout compilateur effectue une analyse statique lors de la compilation. Cependant, dans les grands projets du monde réel, il devient souvent nécessaire de vérifier la conformité de l'ensemble du code avec certaines exigences supplémentaires. Ces exigences peuvent être très diverses, allant des règles de nommage des variables à la portabilité (par exemple, le code doit s'exécuter en toute sécurité sur les plates-formes x86 et x64). Les exigences les plus courantes sont :

  • Fiabilité - moins de bugs dans le programme testé.
  • Maintenabilité - code plus compréhensible, facile à modifier et à améliorer.
  • Portabilité - la flexibilité du programme testé lors de l'exécution sur différentes plates-formes.
  • Lisibilité - réduction du temps nécessaire pour comprendre le code.

Les exigences peuvent être décomposées en règles et directives. Les règles, contrairement aux recommandations, sont contraignantes. Les règles et les recommandations sont analogues aux erreurs et aux avertissements émis par les analyseurs de code intégrés aux compilateurs standard.

Les règles et les directives forment à leur tour la norme de codage. Cette norme définit comment un programmeur doit écrire du code de programme. Les normes de codage sont utilisées par les organisations de développement de logiciels.

L'analyseur statique trouve les lignes de code source qui ne semblent pas conformes à la norme de codage acceptée et affiche des messages de diagnostic afin que le développeur puisse comprendre la cause du problème. Le processus d'analyse statique est similaire à la compilation, sauf qu'aucun objet ni code exécutable n'est généré. Cette vue d'ensemble fournit une description étape par étape du processus d'analyse statique.

Processus d'analyse

Le processus d'analyse statique se compose de deux étapes principales : la création d'un arbre de code (également appelé ) et l'analyse de cet arbre.

Pour analyser le code source, l'analyseur doit d'abord "comprendre" ce code, c'est-à-dire analysez-le par composition et créez une structure qui décrit le code analysé sous une forme pratique. Ce formulaire s'appelle l'arbre de code. Pour vérifier si le code est conforme à la norme de codage, vous devez créer un tel arbre.

Dans le cas général, l'arbre est construit uniquement pour le fragment de code analysé (par exemple, pour une fonction particulière). Afin de créer un arbre, le code est d'abord traité, puis .

Le lexer est chargé de diviser les données d'entrée en jetons individuels, ainsi que de déterminer le type de ces jetons et de les transmettre séquentiellement à l'analyseur. Le lexer lit le code source ligne par ligne, puis décompose les lignes résultantes en mots réservés, identificateurs et constantes appelés jetons. Après avoir reçu un jeton, le lexer détermine son type.

Considérons un exemple d'algorithme pour déterminer le type d'un lexème.

Si le premier caractère du jeton est un chiffre, le jeton est considéré comme un nombre, si ce caractère est un signe moins, alors c'est un nombre négatif. Si un jeton est un nombre, il peut s'agir d'un entier ou d'un nombre fractionnaire. Si le nombre contient la lettre E, qui définit la notation exponentielle, ou un point décimal, le nombre est considéré comme une fraction, sinon c'est un entier. Notez que cela peut provoquer une erreur lexicale - si le code source analysé contient le jeton "4xyz", l'analyseur lexical le considérera comme un entier 4. Cela générera une erreur de syntaxe que l'analyseur pourra détecter. Cependant, de telles erreurs peuvent également être détectées par le lexer.

Si le jeton n'est pas un nombre, il peut s'agir d'une chaîne. Les constantes de chaîne peuvent être reconnues par des guillemets simples, des guillemets doubles ou tout autre caractère, selon la syntaxe du langage analysé.

Enfin, si le jeton n'est pas une chaîne, il doit s'agir d'un identifiant, d'un mot réservé ou d'un caractère réservé. Si le lexème ne rentre pas dans ces catégories, une erreur lexicale se produit. L'analyseur lexical ne gérera pas cette erreur lui-même - il indiquera seulement à l'analyseur qu'un jeton de type inconnu a été rencontré. L'analyseur traitera cette erreur.

L'analyseur comprend la grammaire de la langue. Il est chargé de détecter les erreurs de syntaxe et de convertir un programme qui ne contient pas de telles erreurs en structures de données appelées arbres de code. Ces structures, à leur tour, sont introduites dans l'analyseur statique et traitées par celui-ci.

Alors que le lexer ne comprend que la syntaxe du langage, l'analyseur comprend également le contexte. Par exemple, déclarons une fonction en langage C :

Int Func() (retourne 0 ;)

L'analyseur lexical traitera cette chaîne et l'analysera en jetons, comme indiqué dans le tableau 1 :

Tableau 1 - Jetons de la chaîne "int Func())(return 0);".

La chaîne sera reconnue comme 8 jetons valides et ces jetons seront transmis à l'analyseur.

Cet analyseur examinera le contexte et découvrira que l'ensemble de jetons donné est une déclaration de fonction qui ne prend aucun paramètre, renvoie un entier et que ce nombre est toujours 0.

L'analyseur le découvrira lorsqu'il créera un arbre de code à partir des jetons fournis par le lexer et analysera cet arbre. Si les jetons et l'arbre construit à partir de ceux-ci sont considérés comme corrects, cet arbre sera utilisé dans l'analyse statique. Sinon, l'analyseur émettra un message d'erreur.

Cependant, le processus de construction d'un arbre de code ne se limite pas à simplement représenter les lexèmes sous forme d'arbre. Considérons ce processus plus en détail.

Arborescence des codes

L'arbre de code représente l'essence des données d'entrée sous la forme d'un arbre, en omettant les détails de syntaxe non essentiels. Ces arbres diffèrent des arbres de syntaxe concrets en ce qu'ils n'ont pas de nœuds qui représentent des signes de ponctuation, comme un point-virgule qui termine une ligne ou une virgule qui est placée entre les arguments de la fonction.

Les analyseurs utilisés pour créer des arborescences de code peuvent être écrits à la main ou ils peuvent être générés par des générateurs d'analyseurs. Les arborescences de codes sont généralement construites de bas en haut.

Lors du développement de nœuds d'arbre, la première chose à faire est généralement de déterminer le niveau de modularité. En d'autres termes, il est déterminé si toutes les constructions du langage seront représentées par des sommets du même type, distingués par des valeurs. A titre d'exemple, considérons la représentation des opérations arithmétiques binaires. Une option consiste à utiliser les mêmes sommets pour toutes les opérations binaires, dont l'un des attributs sera le type d'opération, par exemple "+". Une autre option consiste à utiliser différents types de sommets pour différentes opérations. Dans un langage orienté objet, il peut s'agir de classes telles que AddBinary, SubstractBinary, MultipleBinary, etc. qui héritent de la classe de base abstraite Binary.

À titre d'exemple, considérons deux expressions : 1 + 2 * 3 + 4 * 5 et 1 + 2 * (3 + 4) * 5 (voir Figure 1).

Comme on peut le voir sur la figure, la forme originale de l'expression peut être restaurée en parcourant l'arbre de gauche à droite.

Une fois l'arborescence de code générée et vérifiée, l'analyseur statique peut déterminer si le code source respecte les règles et directives spécifiées dans la norme de codage.

Méthodes d'analyse statique

Il existe de nombreuses méthodes différentes, en particulier l'analyse avec , l'analyse de flux de données, l'analyse de flux de données avec sélection de chemin, etc. Les implémentations spécifiques de ces méthodes sont différentes selon les analyseurs. Cependant, les analyseurs statiques pour différents langages de programmation peuvent utiliser le même code sous-jacent (infrastructure). Ces frameworks contiennent un ensemble d'algorithmes de base qui peuvent être utilisés dans différents analyseurs de code, indépendamment des tâches spécifiques et du langage analysé. L'ensemble des méthodes prises en charge et la mise en œuvre spécifique de ces méthodes dépendront à nouveau de l'infrastructure spécifique. Par exemple, le cadre peut permettre la création facile d'un analyseur qui utilise la traversée d'arborescence de code, mais peut ne pas prendre en charge l'analyse de flux de données.

Bien que les trois méthodes d'analyse statique répertoriées ci-dessus utilisent un arbre de code construit par un analyseur, ces méthodes diffèrent dans leurs tâches et leurs algorithmes.

L'analyse de parcours d'arbre, comme son nom l'indique, est effectuée en parcourant un arbre de code et en effectuant des vérifications pour voir si le code est conforme à une norme de codage acceptée, spécifiée comme un ensemble de règles et de directives. C'est le type d'analyse que font les compilateurs.

L'analyse des flux de données peut être décrite comme le processus de collecte d'informations sur l'utilisation, la définition et les dépendances des données dans le programme en cours d'analyse. L'analyse de flux de données utilise un graphe de flux de commandes généré à partir d'un arbre de code. Ce graphe représente tous les chemins possibles pour l'exécution d'un programme donné : les sommets désignent des fragments de code « droits » sans aucune transition, et les arêtes représentent les transferts de contrôle possibles entre ces fragments. Étant donné que l'analyse est effectuée sans exécuter le programme testé, il est impossible de déterminer avec précision le résultat de son exécution. En d'autres termes, il est impossible de savoir exactement sur quel chemin le contrôle sera transféré. Par conséquent, les algorithmes d'analyse de flux de données se rapprochent du comportement possible, par exemple en considérant les deux branches d'une instruction if-then-else, ou en exécutant le corps d'une boucle while avec une certaine précision. Il y a toujours une limite à la précision, puisque les équations de flux de données sont écrites pour un ensemble de variables, et le nombre de ces variables doit être limité, puisque nous ne considérons que des programmes avec un ensemble fini d'instructions. Par conséquent, il y a toujours une limite supérieure au nombre d'inconnues, ce qui limite la précision. Du point de vue du graphe de flot d'instructions, l'analyse statique considère comme valides tous les chemins possibles pour l'exécution d'un programme. En raison de cette hypothèse, l'analyse des flux de données ne peut fournir que des solutions approximatives pour un ensemble limité de problèmes.

L'algorithme d'analyse de flux de données décrit ci-dessus ne fait pas de distinction entre les chemins, puisque tous les chemins possibles, qu'ils soient réels ou non, qu'ils soient exécutés souvent ou rarement, conduisent toujours à une solution. En pratique, cependant, seule une petite fraction des chemins potentiels est satisfaite. De plus, le code le plus fréquemment exécuté a tendance à être un sous-ensemble encore plus petit de tous les chemins possibles. Il est logique de raccourcir le graphe de flux de commandes analysé et donc de réduire la quantité de calcul en analysant uniquement un sous-ensemble de chemins possibles. L'analyse de sélection de chemin est effectuée sur un graphe de flux d'instructions réduit qui ne contient aucun chemin impossible et des chemins qui ne contiennent pas de code "dangereux". Les critères de choix des chemins sont différents selon les analyseurs. Par exemple, l'analyseur peut considérer uniquement les chemins contenant des déclarations de tableaux dynamiques, considérant ces déclarations comme "dangereuses" selon les paramètres de l'analyseur.

Conclusion

Le nombre de méthodes d'analyse statique et d'analyseurs eux-mêmes augmente d'année en année, ce qui signifie que l'intérêt pour les analyseurs de code statique augmente. La raison de l'intérêt réside dans le fait que les logiciels en cours de développement deviennent de plus en plus complexes et, par conséquent, il devient impossible de vérifier le code manuellement.

Dans cet article, une brève description du processus d'analyse statique et des diverses méthodes pour effectuer une telle analyse a été donnée.

Liste bibliographique

  • Dirk Giesen Philosophie et mise en œuvre pratique des outils d'analyse statique. -Données électroniques. -Dirk Giesen, flic. 1998.
  • Bases du compilateur James Alan Farrell. -Données électroniques. -James Alan Farrell, flic 1995. -Mode d'accès : http://www.cs.man.ac.uk/~pjj/farrell/compmain.html
  • Joel Jones Idiomes d'implémentation d'arbre de syntaxe abstraite. -Actes de la 10e Conférence sur les langages de modèles de programmes 2003, cop 2003.
  • Ciera Nicole Christopher Évaluation des cadres d'analyse statique .- Ciera Nicole, cop. 2006.
  • Leon Moonen Une architecture générique pour l'analyse de flux de données pour soutenir l'ingénierie inverse . - Actes du 2e Atelier international sur la théorie et la pratique des spécifications algébriques, cop. 1997.

Avec l'analyse statique, vous pouvez trouver de nombreux défauts et faiblesses différents dans le code source avant même que le code ne soit prêt à être exécuté. D'autre part, l'analyse d'exécution, ou analyse d'exécution, a lieu sur le logiciel en cours d'exécution et détecte les problèmes au fur et à mesure qu'ils surviennent, généralement à l'aide d'outils sophistiqués. On pourrait soutenir qu'une forme d'analyse précède l'autre, mais les développeurs peuvent combiner les deux méthodes pour accélérer les processus de développement et de test, ainsi que pour améliorer la qualité du produit livré.

Cet article considère d'abord la méthode d'analyse statique. Il peut prévenir les problèmes avant qu'ils ne pénètrent dans le code principal et garantir que le nouveau code est conforme à la norme. À l'aide de diverses techniques d'analyse, telles que l'arbre de syntaxe abstraite (AST) et l'analyse du chemin de code, les outils d'analyse statique peuvent découvrir des vulnérabilités cachées, des erreurs logiques, des défauts d'implémentation et d'autres problèmes. Cela peut se produire à la fois au stade du développement sur chaque poste de travail et lors de l'assemblage du système. Le reste de l'article explore une méthode d'analyse dynamique qui peut être utilisée pendant la phase de développement du module et d'intégration du système, et qui vous permet d'identifier les problèmes manqués par l'analyse statique. L'analyse dynamique détecte non seulement les erreurs liées aux pointeurs et autres inexactitudes, mais il est également possible d'optimiser l'utilisation des cycles CPU, de la RAM, de la mémoire flash et d'autres ressources.

L'article traite également des options permettant de combiner l'analyse statique et dynamique, ce qui aidera à empêcher la régression vers des stades de développement antérieurs à mesure que le produit mûrit. Cette approche à double méthode permet d'éviter la plupart des problèmes au début du développement, lorsqu'ils sont les plus faciles et les moins chers à résoudre.

Combiner le meilleur des deux mondes

Les outils d'analyse statique détectent les bogues au début de la création d'un projet, généralement avant la création de l'exécutable. Cette détection précoce est particulièrement utile pour les grands projets de systèmes embarqués où les développeurs ne peuvent pas utiliser les outils d'analyse dynamique tant que le logiciel n'est pas suffisamment complet pour s'exécuter sur le système cible.

Au stade de l'analyse statique, les zones du code source présentant des points faibles sont découvertes et décrites, y compris les vulnérabilités cachées, les erreurs logiques, les défauts d'implémentation, les erreurs dans les opérations parallèles, les conditions aux limites qui se produisent rarement et de nombreux autres problèmes. Par exemple, les outils d'analyse statique Klocwork Insight effectuent une analyse approfondie du code source aux niveaux syntaxique et sémantique. Ces outils effectuent également une analyse inter-procédurale sophistiquée des flux de contrôle et de données et utilisent des techniques de leurre avancées, évaluent les valeurs que prendront les variables et modélisent le comportement potentiel du programme au moment de l'exécution.

Les développeurs peuvent utiliser des outils d'analyse statique à tout moment pendant la phase de développement, même lorsque seuls des fragments du projet ont été écrits. Cependant, plus le code est complet, mieux c'est. Avec l'analyse statique, tous les chemins d'exécution de code potentiels peuvent être visualisés - cela se produit rarement dans les tests normaux, à moins que le projet ne nécessite une couverture de code à 100 %. Par exemple, l'analyse statique peut détecter des erreurs de programmation associées à des conditions de bord ou des erreurs de chemin non testées au moment de la conception.

Étant donné que l'analyse statique tente de prédire le comportement d'un programme basé sur un modèle de code source, on trouve parfois un "bogue" qui n'existe pas réellement - c'est ce qu'on appelle le "faux positif" (faux positif). De nombreux outils d'analyse statique modernes mettent en œuvre des techniques améliorées pour éviter ce problème et effectuer une analyse exceptionnellement précise.

Analyse statique : arguments "pour" Analyse statique : arguments contre
Utilisé tôt dans le cycle de vie du logiciel, avant que le code ne soit prêt à être exécuté et avant le début des tests.

Les bases de code existantes qui ont déjà été testées peuvent être analysées.

Les outils peuvent être intégrés à l'environnement de développement dans le cadre d'un composant utilisé dans les "constructions nocturnes" et dans le cadre de la boîte à outils de l'atelier du développeur.

Faible coût : pas besoin de créer des programmes de test ou des stubs ; les développeurs peuvent exécuter leurs propres analyses.

Des bogues logiciels et des vulnérabilités peuvent être découverts qui n'entraînent pas nécessairement l'échec du programme ou n'affectent pas le comportement du programme lors de son exécution réelle.

Probabilité non nulle de "faux positif".

Tableau 1- Arguments "pour" et "contre" analyse statique.

Les outils d'analyse dynamique détectent les erreurs de programmation dans le code en cours d'exécution. Parallèlement, le développeur a la possibilité d'observer ou de diagnostiquer le comportement de l'application lors de son exécution, dans l'idéal, directement dans l'environnement cible.

Dans de nombreux cas, l'outil d'analyse dynamique modifie le code d'application source ou binaire pour installer des pièges, ou crochets, pour les mesures instrumentales. Ces crochets peuvent être utilisés pour détecter les erreurs de programme au moment de l'exécution, analyser l'utilisation de la mémoire, la couverture du code et vérifier d'autres conditions. Les outils d'analyse dynamique peuvent générer des informations précises sur l'état de la pile, ce qui permet aux débogueurs de trouver la cause d'une erreur. Par conséquent, lorsque les outils d'analyse dynamique trouvent un bogue, il s'agit très probablement d'un bogue réel que le programmeur peut rapidement identifier et corriger. Il convient de noter que pour créer une situation d'erreur au moment de l'exécution, il doit y avoir exactement les conditions nécessaires dans lesquelles une erreur de programme se produit. En conséquence, les développeurs doivent créer une sorte de cas de test pour implémenter un scénario particulier.

Analyse dynamique : arguments "pour" Analyse dynamique : arguments contre
Rarement des "faux positifs" se produisent - productivité élevée dans la recherche d'erreurs

Une trace complète de la pile et de l'exécution peut être générée pour retracer la cause de l'erreur.

Les erreurs sont capturées dans le contexte d'un système en cours d'exécution, à la fois dans le monde réel et en mode simulation.

Il y a une intervention dans le comportement du système en temps réel ; le degré d'intervention dépend du nombre d'inserts d'outils utilisés. Cela ne pose pas toujours de problèmes, mais c'est quelque chose à garder à l'esprit lorsque vous travaillez avec du code à temps critique.

L'exhaustivité de l'analyse des erreurs dépend du degré de couverture du code. Ainsi, le chemin de code contenant l'erreur doit être traversé et, dans le cas de test, les conditions nécessaires doivent être créées pour créer une situation d'erreur.

Tableau 2- Arguments "pour" et "contre" analyse dynamique.

Détection précoce des erreurs pour réduire les coûts de développement

Plus tôt une erreur logicielle est détectée, plus elle peut être corrigée rapidement et à moindre coût. Par conséquent, les outils d'analyse statique et dynamique sont d'une réelle valeur pour trouver les bogues tôt dans le cycle de vie du logiciel. Diverses études de produits industriels montrent que la correction d'un problème au stade des tests du système (pour confirmer la qualité de son travail, QA) ou après la livraison du système s'avère plus coûteuse de plusieurs ordres de grandeur que la résolution des mêmes problèmes au stade de développement du logiciel. De nombreuses organisations ont leurs propres estimations du coût de la réparation des défauts. Sur la fig. La figure 1 fournit des données sur le problème en discussion, tirées du livre souvent cité de Capers Jones. "Mesure logicielle appliquée".

Riz. un- Au fur et à mesure que le projet progresse, le coût de la correction des défauts logiciels peut augmenter de façon exponentielle. Les outils d'analyse statique et dynamique permettent d'éviter ces coûts en détectant les bogues tôt dans le cycle de vie du logiciel.

Analyse statique

L'analyse statique est dans la pratique du développement logiciel depuis presque aussi longtemps que le développement logiciel lui-même existe. Dans sa forme originale, l'analyse se réduisait à la surveillance du respect des normes de style de programmation (lint). Les développeurs l'utilisaient directement sur leur lieu de travail. Lorsqu'il s'agissait de détecter les erreurs de programmation, les premiers outils d'analyse statique se concentraient sur ce qui était en surface : le style de programmation et les erreurs de syntaxe courantes. Par exemple, même les outils d'analyse statique les plus simples peuvent détecter une erreur comme celle-ci :

int foo(int x, int* ptr) ( if(x & 1); ( *ptr = x; return; ) ... )

Ici, l'utilisation erronée d'un point-virgule supplémentaire conduit à des résultats potentiellement désastreux : le pointeur du paramètre d'entrée de la fonction est redéfini dans des conditions inattendues. Le pointeur est toujours redéfini, quelle que soit la condition vérifiée.

Les premiers outils d'analyse se concentraient principalement sur les erreurs de syntaxe. Ainsi, bien que des bogues sérieux aient pu être trouvés, la plupart des problèmes trouvés étaient relativement insignifiants. De plus, un contexte de code suffisamment petit a été fourni pour les outils afin que des résultats précis puissent être attendus. En effet, le travail a été effectué au cours d'un cycle de développement de compilation/liaison typique, et ce que le développeur faisait n'était qu'un petit morceau de code dans un grand système logiciel. Une telle lacune a conduit au fait que les outils d'analyse étaient basés sur des estimations et des hypothèses concernant ce qui pourrait se passer en dehors du "bac à sable" du développeur. Et cela, à son tour, a conduit à la génération d'un volume accru de rapports avec des "faux positifs".

Les générations suivantes d'outils d'analyse statique ont comblé ces lacunes et étendu leur portée au-delà de l'analyse syntaxique et sémantique. Dans les nouveaux outils, une représentation étendue ou un modèle du code généré a été construit (quelque chose de similaire à la phase de compilation), puis toutes les manières possibles d'exécuter le code ont été modélisées conformément au modèle. Ensuite, des flux logiques ont été mappés sur ces chemins avec un contrôle simultané de la manière et de l'endroit où les objets de données sont créés, utilisés et détruits. Dans le processus d'analyse des modules de programme, les procédures d'analyse du contrôle interprocédural et du flux de données peuvent être connectées. Il minimise également les "faux positifs" en utilisant de nouvelles approches pour couper les faux chemins, évaluer les valeurs que les variables peuvent prendre et modéliser le comportement potentiel lors de l'exécution en temps réel. Pour générer des données de ce niveau dans les outils d'analyse statique, il est nécessaire d'analyser l'ensemble de la base de code du projet, de réaliser une mise en page intégrale du système, et pas seulement de travailler avec les résultats obtenus dans le "sandbox" sur le bureau du développeur.

Pour effectuer ces formes d'analyse sophistiquées, les outils d'analyse statique traitent deux principaux types de vérifications de code :

  • Vérification de l'arbre de syntaxe abstraite- vérifier la syntaxe de base et la structure du code.
  • Analyse du chemin de code- pour effectuer une analyse plus complète, qui dépend de la compréhension de l'état des objets de données du programme à un point particulier du chemin d'exécution du code.

Arbres de syntaxe abstraite

Un arbre de syntaxe abstraite est simplement une représentation arborescente du code source, telle qu'elle pourrait être générée dans les étapes de pré-compilation. L'arborescence contient une décomposition un à un détaillée de la structure du code, permettant aux outils d'effectuer une recherche simple des points de syntaxe anormaux.

Il est très facile de construire un vérificateur qui vérifie les normes concernant les conventions de nommage et les restrictions d'appel de fonction, telles que la vérification des bibliothèques non sécurisées. Le but des vérifications AST est généralement de tirer une sorte d'inférence du code lui-même sans utiliser la connaissance de la façon dont le code se comporte pendant l'exécution.

De nombreux outils proposent des vérifications basées sur AST pour une variété de langages, y compris des outils open source tels que PMD pour Java. Certains outils utilisent une grammaire X-path ou une grammaire dérivée de X-path pour définir les conditions qui intéressent les programmes de contrôle. D'autres outils fournissent des mécanismes avancés pour permettre aux utilisateurs de créer leurs propres vérificateurs basés sur AST. Ce type d'examen est relativement facile à réaliser et de nombreuses organisations créent de nouveaux programmes d'examen de ce type pour vérifier la conformité aux normes de codage de l'entreprise ou aux meilleures pratiques recommandées par l'industrie.

Analyse du chemin de code

Prenons un exemple plus complexe. Maintenant, au lieu de rechercher des cas de violations de style de programmation, nous voulons vérifier si la tentative de déréférencement du pointeur fonctionnera correctement ou échouera :

Si(x & 1) ptr = NULL ; *ptr = 1 ;

Un examen superficiel du fragment conduit à la conclusion évidente que la variable ptr peut être NULL si la variable x est impaire, et cette condition, une fois déréférencée, conduira inévitablement à une page nulle. Cependant, lors de la création d'un programme de test basé sur AST, trouver une telle erreur de programme est très problématique. Considérez l'arborescence AST (simplifiée pour plus de clarté) qui serait générée pour l'extrait de code ci-dessus :

Bloc d'instructions If-statement Check-Expression Binary-operator & x 1 True-Branch Expression-statement Assignment-operator = ptr 0 Expression-statement Assignment-operator = Dereference-pointer - ptr 1 les nœuds ne parviennent pas à détecter sous une forme raisonnablement généralisée une tentative (au moins parfois invalide) de déréférencer le pointeur ptr. Par conséquent, l'outil d'analyse ne peut pas simplement rechercher le modèle de syntaxe. Il est également nécessaire d'analyser le cycle de vie des objets de données tels qu'ils apparaissent et sont utilisés dans la logique de contrôle lors de l'exécution.

L'analyse du chemin de code trace les objets dans les chemins d'exécution afin que les validateurs puissent déterminer si les données sont utilisées avec précision et correctement. L'utilisation de l'analyse du chemin de code élargit l'éventail des questions auxquelles il est possible de répondre au cours de l'analyse statique. Au lieu d'analyser simplement l'exactitude du code d'un programme, l'analyse du chemin du code tente de déterminer les "intentions" du code et de vérifier si le code est écrit conformément à ces intentions. Cela peut apporter des réponses aux questions suivantes :

  • L'objet nouvellement créé a-t-il été libéré avant que toutes les références à celui-ci ne soient supprimées de la portée ?
  • La plage de valeurs autorisée a-t-elle été vérifiée pour certains objets de données avant que l'objet ne soit transmis à la fonction du système d'exploitation ?
  • La chaîne de caractères a-t-elle été vérifiée pour les caractères spéciaux avant de transmettre la chaîne en tant que requête SQL ?
  • L'opération de copie provoquera-t-elle un débordement de tampon ?
  • Est-il sûr d'appeler cette fonction à ce moment ?

En analysant les chemins d'exécution du code de cette manière, à la fois du déclenchement de l'événement au script cible et du déclenchement de l'événement à l'initialisation des données requises, l'outil sera en mesure de répondre aux questions et d'émettre un rapport d'erreur si le script cible ou les initialisations sont exécutés. ou non exécuté comme prévu.

La mise en œuvre d'une telle capacité est essentielle pour effectuer une analyse avancée du code source. Par conséquent, les développeurs doivent rechercher des outils qui utilisent une analyse avancée du chemin de code pour détecter les fuites de mémoire, les déréférencements de pointeurs non valides, les transferts de données non sécurisés ou non valides, les violations de concurrence et de nombreuses autres conditions problématiques.

Séquence d'actions lors de l'exécution d'une analyse statique

L'analyse statique permet de détecter des problèmes à deux moments clés du processus de développement : lors de l'écriture du programme sur le lieu de travail et au stade de l'enchaînement du système. Comme déjà mentionné, la génération actuelle d'outils fonctionne principalement à l'étape de liaison du système, lorsqu'il est possible d'analyser le flux de code de l'ensemble du système, ce qui conduit à des résultats de diagnostic très précis.

Unique en son genre, Klocwork Insight vous permet d'analyser le code créé sur le lieu de travail d'un développeur particulier, tout en évitant les problèmes liés aux diagnostics inexacts, qui sont généralement caractéristiques des outils de ce type. Klocwork fournit Connected Desktop Analysis, qui analyse le code d'un développeur avec une compréhension de toutes les dépendances du système. Cela se traduit par une analyse locale qui est tout aussi précise et puissante que l'analyse système centralisée, mais le tout avant que le code ne soit entièrement assemblé.

Du point de vue du séquencement d'analyse, cette capacité permet au développeur d'effectuer une analyse statique précise et de haute qualité très tôt dans le cycle de vie du développement. Klockwork Insight signale tous les problèmes à l'environnement intégré du développeur (IDE) ou à la ligne de commande lorsque le développeur écrit du code et compile/lien périodiquement. L'émission de tels messages et rapports a lieu avant que l'analyse dynamique ne soit effectuée et avant que tous les développeurs ne rassemblent leurs codes.

Riz. 2- Séquence d'exécution de l'analyse statique.

Technologie d'analyse dynamique

Pour détecter les erreurs de programmation dans les outils d'analyse dynamique, de petits fragments de code sont souvent insérés soit directement dans le code source du programme (injection dans le code source) soit dans du code exécutable (injection dans le code objet). Dans de tels segments de code, un "contrôle sanitaire" de l'état du programme est effectué et un rapport d'erreur est émis si quelque chose s'avère incorrect ou inutilisable. D'autres fonctions peuvent être impliquées dans ces outils, telles que le suivi de l'allocation et de l'utilisation de la mémoire dans le temps.

La technologie d'analyse dynamique comprend :

  • Placement d'inserts dans le code source au stade du prétraitement– un fragment de code spécial est inséré dans le code source de l'application avant la compilation pour détecter les erreurs. Cette approche ne nécessite pas de connaissances détaillées de l'environnement d'exécution et, par conséquent, cette méthode est populaire parmi les outils de test et d'analyse des systèmes embarqués. Un exemple d'un tel outil est le produit IBM Rational Test RealTime.
  • Placer des insertions dans le code objet- Pour un tel outil d'analyse dynamique, vous devez avoir une connaissance suffisante de l'environnement d'exécution pour pouvoir insérer du code directement dans des fichiers exécutables et des bibliothèques. Avec cette approche, vous n'avez pas besoin d'accéder au code source du programme ou de relier l'application. Un exemple d'un tel outil est IBM Rational Purify.
  • Insertion de code au moment de la compilation– le développeur utilise des clés spéciales (options) du compilateur pour l'incorporation dans le code source. La capacité du compilateur à détecter les erreurs est utilisée. Par exemple, le compilateur GNU C/C++ 4.x utilise la technologie Mudflap pour détecter les problèmes avec les opérations de pointeur.
  • Bibliothèques d'exécution spécialisées– pour détecter les erreurs dans les paramètres passés, le développeur utilise des versions de débogage des bibliothèques système. Les fonctions comme strcpy() sont notoires en raison de la possibilité de pointeurs nuls ou erronés lors de l'exécution. Lors de l'utilisation de versions de débogage de bibliothèques, de tels paramètres "mauvais" sont détectés. Cette technologie ne nécessite pas de reconnexion de l'application et affecte les performances dans une moindre mesure que l'utilisation complète des insertions dans le code source/objet. Cette technologie est utilisée dans l'outil d'analyse RAM de l'IDE QNX® Momentics®.

Dans cet article, nous examinerons les technologies utilisées dans les outils de développement QNX Momentics, avec un accent particulier sur GCC Mudflap et les bibliothèques d'exécution spécialisées.

GNU C/C++ Mudflap : injection au moment de la compilation dans le code source

L'outil Mudflap, présent dans la version 4.x du compilateur GNU C/C++ (GCC), utilise l'injection au moment de la compilation dans le code source. Dans le même temps, lors de l'exécution, les structures sont vérifiées et comportent potentiellement la possibilité d'erreurs. Mudflap se concentre sur les opérations de pointeur, car elles sont la source de nombreuses erreurs d'exécution pour les programmes écrits en C et C++.

Avec Mudflap activé, le compilateur GCC a une autre passe lorsqu'il insère le code de vérification pour les opérations de pointeur. Le code collé effectue généralement un contrôle de validation sur les valeurs des pointeurs passés. Des valeurs de pointeur incorrectes entraîneront l'envoi de messages par GCC au périphérique de sortie d'erreur standard de la console (stderr). Le vérificateur de pointeur de Mudflap ne se contente pas de vérifier les pointeurs pour null : sa base de données stocke les adresses mémoire des objets réels et des propriétés d'objet, telles que l'emplacement du code source, l'horodatage, la trace de la pile lorsque la mémoire est allouée et désallouée. Une telle base de données vous permet d'obtenir rapidement les données nécessaires lors de l'analyse des opérations d'accès à la mémoire dans le code source du programme.

Les fonctions de bibliothèque comme strcpy() ne vérifient pas les paramètres passés. De telles fonctions ne sont pas non plus testées par Mudflap. Cependant, dans Mudflap, il est possible de créer un wrapper de symboles pour les bibliothèques liées statiquement ou un insert pour les bibliothèques dynamiques. Avec cette technologie, une couche supplémentaire est créée entre l'application et la bibliothèque, ce qui permet de vérifier la validité des paramètres et d'émettre un message sur l'apparition d'écarts. Mudflap utilise un algorithme heuristique basé sur la connaissance des limites de mémoire utilisées par l'application (tas, pile, code et segments de données, etc.) pour déterminer si les valeurs de pointeur renvoyées sont valides.

À l'aide des options de ligne de commande du compilateur GCC, un développeur peut activer les fonctionnalités de Mudflap pour insérer des fragments de code et contrôler le comportement, telles que la gestion des violations (limites, valeurs), la réalisation de vérifications et de paramètres supplémentaires, l'activation de l'heuristique et de l'autodiagnostic. Par exemple, le commutateur -fmudflap définit la configuration par défaut de Mudflap. Les messages du compilateur concernant les violations détectées par Mudflap sont envoyés à la console de sortie (stderr) ou à la ligne de commande. La sortie détaillée fournit des informations sur la violation et les variables et fonctions impliquées, ainsi que l'emplacement du code. Ces informations peuvent être automatiquement importées dans l'EDI, où elles sont rendues et tracées dans la pile. À l'aide de ces données, le développeur peut naviguer rapidement vers l'endroit approprié dans le code source du programme.

Sur la fig. La figure 3 montre un exemple de présentation d'une erreur dans l'IDE, ainsi que les informations de trace correspondantes. Le backtrace fonctionne comme un lien vers le code source, permettant au développeur de diagnostiquer rapidement la cause du problème.

L'utilisation de Mudflap peut augmenter le temps de liaison et réduire les performances au moment de l'exécution. Les données présentées dans l'article "Mudflap : Pointer Use Checking for C/C++" indiquent qu'avec Mudflap activé, le temps de liaison augmente de 3 à 5 fois et le programme commence à s'exécuter 1,25 à 5 fois plus lentement. Il est clair que les développeurs de Les applications urgentes doivent utiliser cette fonctionnalité avec prudence. Cependant, Mudflap est un outil puissant pour identifier les constructions de code sujettes aux erreurs et potentiellement fatales. QNX prévoit d'utiliser l'outil Mudflap dans les futures versions de leurs outils d'analyse dynamique.

Riz. 3- Utilisation des informations de backtrace affichées dans l'IDE QNX Momentics pour trouver le code source qui a causé l'erreur.

Versions de débogage des bibliothèques d'exécution

Parallèlement à l'utilisation d'inserts de débogage spéciaux dans les bibliothèques d'exécution, qui entraînent des coûts de mémoire et de temps supplémentaires importants aux étapes de liaison et d'exécution, les développeurs peuvent utiliser des bibliothèques d'exécution pré-instrumentées. Dans de telles bibliothèques, du code est ajouté autour des appels de fonction, dont le but est de vérifier la validité des paramètres d'entrée. Par exemple, considérons un vieil ami, la fonction de copie de chaîne :

strcpy(a,b);

Il prend deux paramètres, qui sont tous deux des pointeurs vers un type carboniser: un pour la chaîne d'origine ( b) et une autre pour la chaîne de résultat ( une). Malgré cette simplicité, cette fonction peut être source de nombreuses erreurs :

  • si la valeur du pointeur une est nul ou non valide, la copie vers cette destination entraînera une erreur d'accès à la mémoire refusé ;
  • si la valeur du pointeur b est nul ou non valide, la lecture des informations à partir de cette adresse entraînera une erreur d'accès à la mémoire refusé ;
  • si en bout de ligne b si le caractère de fin "0" est manquant, plus de caractères que prévu seront copiés dans la chaîne de destination ;
  • si la taille de la chaîne b plus que la mémoire allouée pour la chaîne une, alors plus d'octets que prévu seront écrits à l'adresse spécifiée (scénario typique de débordement de la mémoire tampon).

La version de débogage de la bibliothèque vérifie les valeurs des paramètres ‘ une' et ' b'. Les longueurs de chaîne sont également vérifiées pour s'assurer qu'elles sont compatibles. Si un paramètre invalide est trouvé, un message d'alarme approprié est émis. Dans l'environnement QNX Momentics, ces messages d'erreur sont importés du système cible et affichés à l'écran. L'environnement QNX Momentics utilise également la technologie de suivi d'allocation et de désallocation de mémoire pour permettre une analyse approfondie de l'utilisation de la RAM.

La version de débogage de la bibliothèque fonctionnera avec n'importe quelle application qui utilise ses fonctions ; vous n'avez pas besoin d'apporter de modifications supplémentaires au code. De plus, le développeur peut ajouter la bibliothèque au démarrage de l'application. La bibliothèque remplacera alors les parties correspondantes de la bibliothèque standard complète, éliminant ainsi le besoin d'utiliser une version de débogage de la bibliothèque complète. Dans l'IDE QNX Momentics, un développeur peut ajouter une telle bibliothèque au démarrage du programme dans le cadre d'une session de débogage interactive normale. Sur la fig. La figure 4 montre un exemple de la façon dont QNX Momentics détecte et signale les erreurs de mémoire.

Les versions de débogage des bibliothèques fournissent une méthode "non agressive" éprouvée pour détecter les erreurs lors de l'appel des fonctions de la bibliothèque. Cette technique est idéale pour l'analyse RAM et d'autres méthodes d'analyse qui dépendent de paires d'appels appariés, telles que malloc() et free(). En d'autres termes, cette technologie ne peut détecter que les erreurs d'exécution pour le code avec des appels de bibliothèque. Il ne détecte pas beaucoup d'erreurs courantes, telles que les déréférencements de pointeur en ligne ou l'arithmétique de pointeur incorrecte. En règle générale, lors du débogage, seul un sous-ensemble des appels système est surveillé. Vous pouvez en savoir plus à ce sujet dans l'article.

Riz. 4- L'analyse de la RAM se fait en plaçant des pièges dans la zone des appels d'API liés à l'accès à la mémoire.

Séquence d'actions en analyse dynamique

En bref, l'analyse dynamique implique la capture d'événements de violation ou d'autres événements significatifs dans le système cible intégré, l'importation de ces informations dans l'environnement de développement, puis l'utilisation d'outils de visualisation pour identifier rapidement les sections de code boguées.

Comme le montre la fig. 5, l'analyse dynamique vous permet non seulement de détecter les erreurs, mais aide également à attirer l'attention du développeur sur les détails de la consommation de mémoire, des cycles CPU, de l'espace disque et d'autres ressources. Le processus d'analyse se compose de plusieurs étapes, et un bon outil d'analyse dynamique fournit un support solide pour chaque étape :

  1. Observation- Tout d'abord, il capture les erreurs d'exécution, détecte les fuites de mémoire et affiche tous les résultats dans l'IDE.
  2. Ajustement- le développeur a alors la possibilité de retracer chaque erreur jusqu'à la ligne source incriminée. Avec une bonne intégration dans l'IDE, chaque erreur sera affichée à l'écran. Le développeur doit simplement cliquer sur la ligne de l'erreur et le fragment de code source s'ouvre avec la ligne qui interrompt le travail. Dans de nombreux cas, un développeur peut rapidement résoudre un problème en utilisant la trace de pile disponible et des outils de code source supplémentaires dans l'IDE (visualiseurs d'appels de fonction, traceurs d'appels, etc.).
  3. Profilage– En corrigeant les bogues détectés et les fuites de mémoire, le développeur peut analyser l'utilisation des ressources au fil du temps, y compris les pics, les moyennes de charge et les dépassements de ressources. Idéalement, l'outil d'analyse fournira une représentation visuelle de l'utilisation des ressources à long terme, vous permettant d'identifier immédiatement les pics d'allocation de mémoire et d'autres anomalies.
  4. Optimisation– en utilisant les informations de l'étape de profilage, le développeur peut maintenant effectuer une analyse "fine" de l'utilisation des ressources du programme. Entre autres choses, de telles optimisations peuvent minimiser les pics de ressources et la surutilisation, y compris l'utilisation de la RAM et du processeur.

Riz. 5- Séquence typique d'actions pour l'analyse dynamique

Combiner la séquence d'actions de différents types d'analyse dans l'environnement de développement

Chacun des outils d'analyse statique et dynamique a ses propres forces. Par conséquent, les équipes de développement doivent utiliser ces outils en tandem. Par exemple, les outils d'analyse statique sont capables de détecter les erreurs manquées par les outils d'analyse dynamique, car les outils d'analyse dynamique ne détectent une erreur que si le morceau de code erroné est exécuté pendant le test. D'autre part, les outils d'analyse dynamique détectent les erreurs logicielles dans le processus d'exécution final. Il n'est guère nécessaire d'avoir une discussion sur l'erreur si l'utilisation d'un pointeur nul a déjà été découverte.

Idéalement, un développeur utilisera les deux outils d'analyse dans son travail quotidien. La tâche est grandement facilitée si les outils sont bien intégrés à l'environnement de développement en milieu de travail.

Voici un exemple d'utilisation conjointe de deux types d'outils :

  1. Au début de la journée de travail, le développeur consulte le rapport sur les résultats de la génération nocturne. Ce rapport inclut à la fois les erreurs de génération elles-mêmes et les résultats de l'analyse statique effectuée pendant la génération.
  2. Le rapport d'analyse statique répertorie les défauts détectés ainsi que des informations qui vous aideront à les corriger, y compris des liens vers le code source. À l'aide de l'IDE, le développeur peut signaler chaque situation comme un vrai bogue ou un "faux positif". Après cela, les erreurs réelles présentes sont corrigées.
  3. Le développeur enregistre les modifications apportées localement, dans l'IDE, ainsi que tous les nouveaux extraits de code. Le développeur ne valide pas ces modifications dans le système de contrôle source tant que les modifications n'ont pas été examinées et testées.
  4. Le développeur analyse et corrige le nouveau code à l'aide d'un outil d'analyse statique sur le lieu de travail local. Afin d'être sûr d'une détection d'erreur de haute qualité et de l'absence de "faux positifs", l'analyse utilise des informations étendues au niveau du système. Ces informations sont extraites du processus de construction/analyse nocturne.
  5. Après avoir analysé et "nettoyé" tout nouveau code, le développeur construit le code dans une image de test locale ou un exécutable.
  6. À l'aide d'outils d'analyse dynamique, le développeur exécute des tests pour vérifier les modifications apportées.
  7. Avec l'aide de l'IDE, le développeur peut rapidement identifier et corriger les bogues signalés via les outils d'analyse dynamique. Le code est considéré comme final et prêt à l'emploi lorsqu'il a subi une analyse statique, des tests unitaires et une analyse dynamique.
  8. Le développeur soumet les modifications au système de contrôle de code source ; après cela, le code modifié participe au processus de liaison nocturne suivant.

Ce flux de travail est similaire à celui des projets de taille moyenne à grande qui utilisent déjà des builds nocturnes, le contrôle du code source et la propriété du code. Étant donné que les outils sont intégrés à l'IDE, les développeurs effectuent rapidement des analyses statiques et dynamiques sans s'écarter du flux de travail typique. En conséquence, la qualité du code augmente considérablement déjà au stade de la création du code source.

Le rôle de l'architecture RTOS

Dans le cadre de la discussion sur les outils d'analyse statique et dynamique, l'évocation de l'architecture RTOS peut sembler déplacée. Mais il s'avère qu'un RTOS bien construit peut grandement faciliter la détection, la localisation et la résolution de nombreux bogues logiciels.

Par exemple, dans un RTOS à micro-noyau tel que QNX Neutrino, toutes les applications, pilotes de périphériques, systèmes de fichiers et piles réseau résident en dehors du noyau dans des espaces d'adressage distincts. En conséquence, tous sont isolés du noyau et les uns des autres. Cette approche offre le plus haut degré de localisation des défaillances : la défaillance d'un des composants n'entraîne pas l'effondrement du système dans son ensemble. De plus, il s'avère qu'il est facile d'isoler une erreur liée à la RAM ou une autre erreur logique au composant exact qui a causé cette erreur.

Par exemple, si un pilote de périphérique tente d'accéder à la mémoire en dehors de son conteneur de processus, le système d'exploitation peut identifier le processus, indiquer l'emplacement de l'erreur et générer un fichier de vidage pouvant être visualisé par les débogueurs de code source. Dans le même temps, le reste du système continuera de fonctionner et le développeur pourra localiser le problème et travailler à sa résolution.

Riz. 6- Dans un système d'exploitation à micro-noyau, les défaillances de la RAM pour les pilotes, les piles de protocoles et d'autres services n'entraîneront pas de perturbation des autres processus ou du noyau. De plus, le système d'exploitation peut détecter instantanément une tentative non autorisée d'accès à la mémoire et indiquer à partir de quel code cette tentative a été effectuée.

Comparé à un noyau de système d'exploitation conventionnel, le micro-noyau a un temps moyen de réparation (MTTR) inhabituellement court après une panne. Considérez ce qui se passe lorsqu'un pilote de périphérique tombe en panne : le système d'exploitation peut arrêter le pilote, restaurer les ressources utilisées par le pilote et redémarrer le pilote. Cela prend généralement quelques millisecondes. Dans un système d'exploitation monolithique typique, l'appareil doit être redémarré - ce processus peut prendre de quelques secondes à plusieurs minutes.

Remarques finales

Les outils d'analyse statique peuvent détecter les erreurs de programmation avant même que le code ne soit exécuté. Même les erreurs détectées ne sont pas détectées aux étapes de test de bloc, de test du système et également à l'étape d'intégration, car il est très difficile de fournir une couverture complète du code pour les applications complexes, ce qui nécessite des coûts importants. De plus, les équipes de développement peuvent utiliser des outils d'analyse statique lors des versions régulières du système pour s'assurer que chaque nouveau code est analysé.

Parallèlement, des outils d'analyse dynamique prennent en charge les phases d'intégration et de test en signalant à l'environnement de développement les erreurs (ou les problèmes potentiels) qui surviennent lors de l'exécution du programme. Ces outils fournissent également une traçabilité complète jusqu'à l'endroit où l'erreur s'est produite. Grâce à ces informations, les développeurs peuvent effectuer un débogage post-mortem de mystérieux échecs de programme ou de plantages du système en beaucoup moins de temps. L'analyse dynamique via des traces de pile et des variables peut révéler les causes sous-jacentes du problème - c'est mieux que d'utiliser des instructions "if (ptr != NULL)" partout pour prévenir et contourner les plantages.

L'utilisation d'une détection précoce, d'une couverture de test de code meilleure et complète, ainsi que de la correction d'erreurs, aide les développeurs à créer des logiciels de meilleure qualité dans un délai plus court.

Bibliographie

  • Eigler, Frank Ch., "Mudflap : Pointer Use Checking for C/C++", Actes du GCC Developers Summit 2003, p. 57-70. http://www.linux.org.uk/~ajh/gcc/gccsummit-2003-proceedings.pdf
  • « Heap Analysis: Making Memory Errors a Thing of Past », Guide du programmeur QNX Neutrino RTOS. http://pegasus.ott.qnx.com/download/download/16853/neutrino_prog.pdf

À propos des systèmes logiciels QNX

QNX Software Systems est une filiale de Harman International et l'un des principaux fournisseurs mondiaux de technologies innovantes pour les systèmes embarqués, y compris les intergiciels, les outils de développement et les systèmes d'exploitation. Le QNX® Neutrino® RTOS, le kit de développement QNX Momentics® et le middleware QNX Aviage®, basés sur une architecture modulaire, forment la suite logicielle la plus robuste et la plus évolutive pour la construction de systèmes embarqués hautes performances. Des entreprises mondiales de premier plan telles que Cisco, Daimler, General Electric, Lockheed Martin et Siemens utilisent largement les technologies QNX dans les routeurs de réseau, les dispositifs médicaux, les unités télématiques pour véhicules, les systèmes de sûreté et de sécurité, les robots industriels et d'autres applications critiques et critiques. Tâches. Le siège social de l'entreprise est situé à Ottawa (Canada) et les distributeurs de produits sont situés dans plus de 100 pays à travers le monde.

À propos de Klocwork

Les produits Klocwork sont conçus pour l'analyse automatisée du code statique, la détection et la prévention des défauts logiciels et des problèmes de sécurité. Nos produits fournissent aux équipes de développement les outils nécessaires pour identifier les causes profondes des défauts de qualité et de sécurité des logiciels, et pour suivre et prévenir ces défauts tout au long du processus de développement. La technologie brevetée de Klocwork a été créée en 1996 et a fourni un retour sur investissement (ROI) élevé à plus de 80 clients, dont beaucoup sont des entreprises du Fortune 500 et offrent les environnements de développement logiciel les plus recherchés au monde. Klocwork est une société privée avec des bureaux à Burlington, San Jose, Chicago, Dallas (USA) et Ottawa (Canada).

Analyser du code binaire, c'est-à-dire du code exécuté directement par une machine, n'est pas une tâche triviale. Dans la plupart des cas, si vous devez analyser un code binaire, il est d'abord restauré par désassemblage, puis décompilé en une représentation de haut niveau, puis ils analysent ce qui s'est passé.

Il faut dire ici que le code qui a été restauré, en termes de représentation textuelle, n'a que peu de choses en commun avec le code initialement écrit par le programmeur et compilé dans un fichier exécutable. Il est impossible de restaurer exactement un fichier binaire obtenu à partir de langages de programmation compilés tels que C / C ++, Fortran, car il s'agit d'une tâche algorithmiquement non formalisée. Dans le processus de conversion du code source que le programmeur a écrit dans le programme que la machine exécute, le compilateur effectue des transformations irréversibles.

Dans les années 90 du siècle dernier, on croyait généralement que le compilateur, comme un hachoir à viande, broyait le programme source, et la tâche de le restaurer est similaire à la tâche de restaurer un mouton à partir d'une saucisse.

Cependant, tout n'est pas mauvais. Lors du processus d'obtention d'une saucisse, le bélier perd sa fonctionnalité, tandis que le programme binaire la conserve. Si la saucisse résultante pouvait courir et sauter, les tâches seraient similaires.

Ainsi, puisque le programme binaire a conservé sa fonctionnalité, on peut dire qu'il est possible de restaurer le code exécutable dans une représentation de haut niveau afin que la fonctionnalité du programme binaire, dont la représentation originale n'existe pas, et le programme , dont nous avons reçu la représentation textuelle, sont équivalentes.

Par définition, deux programmes sont fonctionnellement équivalents si, étant donné la même entrée, tous deux terminent ou ne parviennent pas à terminer leur exécution et, si l'exécution se termine, produisent le même résultat.

La tâche de démontage est généralement résolue en mode semi-automatique, c'est-à-dire que le spécialiste effectue la restauration manuellement à l'aide d'outils interactifs, par exemple le désassembleur interactif IdaPro, le radar ou un autre outil. De plus, la décompilation est également effectuée en mode semi-automatique. Comme outil de décompilation pour aider l'homme du métier, utilisez HexRays, SmartDecompiler ou un autre décompilateur adapté à la tâche de décompilation donnée.

La restauration de la représentation textuelle originale du programme à partir du byte-code peut être effectuée de manière assez précise. Pour les langages interprétés tels que Java ou les langages de la famille .NET, qui sont traduits en byte-code, la tâche de décompilation est résolue différemment. Nous n'abordons pas cette question dans cet article.

Ainsi, les programmes binaires peuvent être analysés au moyen de la décompilation. Typiquement, une telle analyse est effectuée pour comprendre le comportement du programme afin de le remplacer ou de le modifier.

De la pratique de travailler avec des programmes hérités

Certains logiciels, écrits il y a 40 ans dans la famille des langages de bas niveau C et Fortran, contrôlent les équipements de production pétrolière. La défaillance de cet équipement peut être critique pour la production, il est donc hautement indésirable de changer de logiciel. Cependant, au fil des ans, les codes sources ont été perdus.

Un nouvel employé du service de sécurité de l'information, dont la responsabilité était de comprendre comment ce qui fonctionne, a découvert que le programme de contrôle du capteur écrit quelque chose sur le disque avec une certaine régularité, mais on ne sait pas ce qu'il écrit et comment ces informations peuvent être utilisées. Il a également eu l'idée que la surveillance de l'équipement pourrait être affichée sur un grand écran. Pour ce faire, il était nécessaire de comprendre comment le programme fonctionne, quoi et dans quel format il écrit sur le disque, comment ces informations peuvent être interprétées.

Pour résoudre le problème, la technologie de décompilation a été utilisée avec une analyse ultérieure du code récupéré. Nous avons d'abord désassemblé les composants logiciels un par un, puis localisé le code qui était responsable de l'entrée/sortie des informations, et progressivement commencé à restaurer à partir de ce code, en tenant compte des dépendances. Ensuite, la logique du programme a été restaurée, ce qui a permis de répondre à toutes les questions du service de sécurité concernant le logiciel analysé.

Si vous devez analyser un programme binaire afin de restaurer la logique de son fonctionnement, restaurer partiellement ou complètement la logique de conversion des données d'entrée en données de sortie, etc., il est pratique de le faire à l'aide d'un décompilateur.

En plus de ces tâches, il existe en pratique des tâches d'analyse de programmes binaires en fonction des exigences de sécurité de l'information. En même temps, le client ne comprend pas toujours que cette analyse est très chronophage. Il semblerait que décompiler et exécuter le code résultant avec un analyseur statique. Mais à la suite d'une analyse qualitative, cela ne fonctionnera presque jamais.

Premièrement, les vulnérabilités trouvées doivent pouvoir non seulement être trouvées, mais aussi expliquées. Si une vulnérabilité a été trouvée dans un programme de langage de haut niveau, l'analyste ou l'outil d'analyse de code y montre quels fragments de code contiennent certaines failles qui ont causé la vulnérabilité. Et s'il n'y a pas de code source ? Comment montrer quel code a causé la vulnérabilité ?

Le décompilateur récupère le code qui est "jonché" d'artefacts de récupération, et il est inutile de mapper la vulnérabilité identifiée à un tel code, rien n'est clair de toute façon. De plus, le code récupéré est mal structuré et se prête donc mal aux outils d'analyse de code. Expliquer une vulnérabilité en termes de programme binaire est également difficile, car la personne à qui l'explication est donnée doit bien connaître la représentation binaire des programmes.

Deuxièmement, l'analyse binaire selon les exigences de sécurité de l'information doit être effectuée avec une compréhension de ce qu'il faut faire avec le résultat, car il est très difficile de corriger une vulnérabilité dans un code binaire, mais il n'y a pas de code source.

Malgré toutes les caractéristiques et les difficultés liées à la réalisation d'une analyse statique de programmes binaires conformément aux exigences de la sécurité de l'information, il existe de nombreuses situations dans lesquelles une telle analyse doit être effectuée. Si, pour une raison quelconque, il n'y a pas de code source et que le programme binaire exécute des fonctionnalités critiques selon les exigences de la sécurité de l'information, il doit être vérifié. Si des vulnérabilités sont découvertes, une telle application doit être envoyée pour révision, si possible, ou un "shell" supplémentaire doit être créé pour elle, ce qui permettra de contrôler le mouvement des informations sensibles.

Lorsque la vulnérabilité était cachée dans un fichier binaire

Si le code que le programme exécute a un niveau de criticité élevé, même si le code source du programme dans un langage de haut niveau est disponible, il est utile d'auditer le fichier binaire. Cela aidera à éliminer les bizarreries que le compilateur pourrait introduire en effectuant des transformations d'optimisation. Ainsi, en septembre 2017, la transformation d'optimisation effectuée par le compilateur Clang a été largement discutée. Son résultat était un appel à une fonction qui ne devrait jamais être appelée.

#inclure typedef int(*Fonction)(); Fonction statique Do ; static int EraseAll() ( return system("rm -rf /"); ) void NeverCalled() ( Do = EraseAll; ) int main() ( return Do(); )

À la suite des transformations d'optimisation, le compilateur recevra un tel code assembleur. L'exemple a été compilé sous Linux X86 avec le drapeau -O2.

Texte. main subl $12, %esp movl $.L.str, (%esp) calll system addl $12, %esp retl .Lfunc_end1: .size main, .Lfunc_end1-main .type .L.str,@object # @.str . section .rodata.str1.1,"aMS",@progbits,1 .L.str : .asciz "rm -rf /" .size .L.str, 9

Il y a un comportement indéfini dans le code source. La fonction NeverCalled() est appelée en raison des conversions d'optimisation effectuées par le compilateur. Au cours du processus d'optimisation, il effectue très probablement une analyse d'alias et, par conséquent, la fonction Do() reçoit l'adresse de la fonction NeverCalled(). Et puisque la méthode main() appelle la fonction Do(), qui n'est pas définie, qui est un comportement indéfini par la norme, le résultat suivant est obtenu : la fonction EraseAll() est appelée, qui exécute le « rm -rf / » commander.

L'exemple suivant : suite à des transformations d'optimisation du compilateur, nous avons perdu la vérification du pointeur pour NULL avant son déréférencement.

#inclure void Checker(int *P) ( int deadVar = *P; if (P == 0) return; *P = 8; )

Étant donné que la ligne 3 déréférence le pointeur, le compilateur suppose que le pointeur n'est pas nul. De plus, la ligne 4 a été supprimée à la suite de l'optimisation "suppression du code inaccessible", puisque la comparaison est considérée comme redondante, et après cela, la ligne 3 a été supprimée par le compilateur à la suite de l'optimisation "élimination du code mort". Il ne reste que la ligne 5. Le code assembleur résultant de la compilation de gcc 7.3 sous Linux x86 avec l'indicateur -O2 est présenté ci-dessous.

Texte .p2align 4,15 .globl _Z7CheckerPi .type _Z7CheckerPi, @function _Z7CheckerPi : movl 4(%esp), %eax movl $8, (%eax) ret

Les exemples d'optimisation du compilateur ci-dessus sont le résultat d'un comportement indéfini UB dans le code. Cependant, il s'agit d'un code parfaitement normal que la plupart des programmeurs supposeront sûr. Aujourd'hui, les programmeurs prennent le temps d'éliminer les comportements indéfinis dans un programme, alors qu'il y a 10 ans ils n'y prêtaient pas attention. Par conséquent, le code hérité peut contenir des vulnérabilités liées à UB.

La plupart des analyseurs de code source statique modernes ne détectent pas les erreurs liées à UB. Par conséquent, si le code exécute une fonctionnalité critique selon les exigences de sécurité de l'information, il est nécessaire de vérifier à la fois ses codes sources et le code lui-même qui sera exécuté.

annotation

Actuellement, un grand nombre d'outils ont été développés pour automatiser la recherche de vulnérabilités logicielles. Cet article discutera de certains d'entre eux.

introduction

L'analyse de code statique est une analyse logicielle qui est effectuée sur le code source des programmes et qui est mise en œuvre sans exécuter réellement le programme à l'étude.

Le logiciel contient souvent diverses vulnérabilités dues à des erreurs dans le code du programme. Les erreurs commises dans le développement des programmes, dans certaines situations, entraînent un plantage du programme, et par conséquent, le fonctionnement normal du programme est perturbé : dans ce cas, les données sont souvent modifiées et corrompues, le programme ou même le système s'arrête . La plupart des vulnérabilités sont liées à un traitement incorrect des données reçues de l'extérieur, ou à une vérification insuffisamment stricte de celles-ci.

Pour identifier les vulnérabilités, divers outils sont utilisés, par exemple des analyseurs statiques du code source du programme, dont un aperçu est donné dans cet article.

Classification des vulnérabilités de sécurité

Lorsque l'exigence que le programme fonctionne correctement sur toutes les données d'entrée possibles est violée, l'apparition de soi-disant vulnérabilités de sécurité (vulnérabilité de sécurité) devient possible. Les vulnérabilités de sécurité peuvent entraîner l'utilisation d'un programme pour surmonter les limitations de sécurité de l'ensemble du système dans son ensemble.

Classification des failles de sécurité en fonction des erreurs logicielles :

  1. Débordement de tampon. Cette vulnérabilité se produit en raison du manque de contrôle sur le tableau hors limites en mémoire lors de l'exécution du programme. Lorsqu'un paquet de données trop volumineux déborde du tampon limité, le contenu des cellules de mémoire superflues est écrasé et le programme se bloque et se bloque. Par l'emplacement du tampon dans la mémoire de processus, les débordements de tampon sont distingués sur la pile (débordement de tampon de pile), le tas (débordement de tampon de tas) et la zone de données statiques (débordement de tampon bss).
  2. Vulnérabilités (vulnérabilité d'entrée entachée). Des vulnérabilités peuvent survenir lorsque l'entrée de l'utilisateur est transmise sans contrôle suffisant à un interpréteur d'un langage externe (généralement un shell Unix ou un langage SQL). Dans ce cas, l'utilisateur peut spécifier les données d'entrée de manière à ce que l'interpréteur lancé exécute une commande complètement différente de celle prévue par les auteurs du programme vulnérable.
  3. Vulnérabilité de chaîne de format. Ce type de vulnérabilité de sécurité est une sous-classe d'une vulnérabilité. Cela provient d'un contrôle insuffisant des paramètres lors de l'utilisation des fonctions d'E/S de format printf, fprintf, scanf, etc. de la bibliothèque standard C. Ces fonctions prennent comme paramètre une chaîne de caractères qui spécifie le format d'entrée ou de sortie des arguments de fonction suivants. Si l'utilisateur peut définir lui-même le type de formatage, cette vulnérabilité pourrait résulter d'un échec de l'application des fonctions de formatage de chaîne.
  4. Vulnérabilités résultant d'erreurs de synchronisation (race conditions). Les problèmes associés au multitâche conduisent à des situations appelées : un programme non conçu pour s'exécuter dans un environnement multitâche peut croire que, par exemple, les fichiers qu'il utilise lors de son exécution ne peuvent pas être modifiés par un autre programme. Par conséquent, un attaquant qui remplace le contenu de ces fichiers de travail à temps peut forcer le programme à effectuer certaines actions.

Bien sûr, en plus de ceux répertoriés, il existe d'autres classes de vulnérabilités de sécurité.

Vue d'ensemble des analyseurs existants

Les outils suivants sont utilisés pour détecter les failles de sécurité dans les programmes :

  • Débogueurs dynamiques. Outils qui vous permettent de déboguer un programme pendant son exécution.
  • Analyseurs statiques (débogueurs statiques). Outils qui utilisent les informations accumulées lors de l'analyse statique du programme.

Les analyseurs statiques indiquent les endroits du programme où une erreur peut être trouvée. Ces extraits de code suspects peuvent contenir un bogue ou être totalement inoffensifs.

Cet article donne un aperçu de plusieurs analyseurs statiques existants. Examinons de plus près chacun d'eux.

1.BONNÉ

Un outil qui, basé sur une analyse sémantique approfondie, automatise le processus d'analyse des textes sources C à la recherche de vulnérabilités pouvant entraîner des débordements de tampon. Il détecte d'éventuels défauts en supposant que certaines valeurs font partie d'un type implicite avec une taille de tampon spécifique.

2.Qualité

Un outil d'analyse pour trouver des erreurs dans les programmes C. Le programme étend le langage C avec des spécificateurs de type supplémentaires définis par l'utilisateur. Le programmeur commente son programme avec les spécificateurs appropriés et cqual vérifie les erreurs. Des annotations incorrectes indiquent des erreurs potentielles. Squal peut être utilisé pour détecter les vulnérabilités potentielles des chaînes de format.

3. VADROUILLES

(MOdel verification Programs for Security) est un outil permettant de trouver des failles de sécurité dans les programmes C. Son but : un ajustement dynamique pour s'assurer que le programme C correspond au modèle statique. MOPS utilise un modèle d'audit logiciel pour aider à déterminer si un programme est conforme à un ensemble de règles définies pour créer un logiciel sécurisé.

4.ITS4, RATS, PScan, Flawfinder

Les analyseurs statiques suivants sont utilisés pour rechercher les erreurs de dépassement de mémoire tampon et les erreurs de chaîne de format :

  1. . Un outil simple qui analyse statiquement le code source C/C++ pour détecter les failles de sécurité potentielles. Il note les appels à des fonctions potentiellement dangereuses telles que strcpy/memcpy et effectue une analyse sémantique superficielle pour tenter d'évaluer la dangerosité d'un tel code, ainsi que des conseils pour l'améliorer.
  2. . L'utilitaire RATS (Rough Auditing Tool for Security) traite le code C/C++ et peut également traiter les scripts Perl, PHP et Python. RATS analyse le code source à la recherche d'appels de fonction potentiellement dangereux. Le but de cet outil n'est pas de trouver définitivement des bogues, mais de fournir des conclusions raisonnables, sur la base desquelles un spécialiste peut effectuer manuellement la vérification du code. RATS utilise une combinaison de contrôles de robustesse de sécurité allant des contrôles sémantiques dans ITS4 à une analyse sémantique approfondie à la recherche de défauts de débordement de tampon dérivés de MOPS.
  3. . Analyse les textes source C pour une utilisation potentiellement incorrecte des fonctions de type printf et trouve des vulnérabilités dans les chaînes de format.
  4. . Comme RATS, c'est un scanner de code source statique pour les programmes écrits en C/C++. Recherche les fonctions les plus couramment utilisées à mauvais escient, leur attribue des scores de risque (sur la base d'informations telles que les paramètres transmis) et compile une liste des vulnérabilités potentielles, en les triant par gravité.

Tous ces outils sont similaires et n'utilisent qu'une analyse lexicale et simple. Par conséquent, les résultats produits par ces programmes peuvent contenir jusqu'à 100 % de faux messages.

5. Bouquet

Un outil d'analyse et de visualisation de programme C qui construit un graphique de dépendance pour aider l'auditeur à comprendre la structure modulaire du programme.

6 ONU

Un simple analyseur de code source. Il a été conçu pour détecter les erreurs telles que les variables non initialisées, les pointeurs nuls et les erreurs de tableau hors limites. UNO vous permet d'effectuer une analyse simple du flux de contrôle et des flux de données, d'effectuer des analyses intra- et inter-procédurales et de spécifier les propriétés de l'utilisateur. Mais cet outil n'a pas été finalisé pour analyser des applications réelles, ne prend pas en charge de nombreuses bibliothèques standard et, à ce stade de développement, ne permet pas d'analyser des programmes sérieux.

7. FlexeLint (PC-Lint)

Cet analyseur est conçu pour analyser le code source afin de détecter différents types d'erreurs. Le programme effectue une analyse sémantique du code source, une analyse des données et des flux de contrôle.

A la fin des travaux, des messages de plusieurs types principaux sont émis :

  • Un pointeur nul est possible ;
  • Problèmes d'allocation de mémoire (par exemple, pas de free() après malloc());
  • Flux de contrôle problématique (par exemple, code inaccessible) ;
  • Débordement de tampon possible, débordement arithmétique ;
  • Avertissements concernant le style de code incorrect et potentiellement dangereux.

8. Viva64

Un outil qui aide un spécialiste à tracer des fragments potentiellement dangereux dans le code source des programmes C/C++ liés à la transition des systèmes 32 bits aux systèmes 64 bits. Viva64 est intégré à l'environnement Microsoft Visual Studio 2005/2008, ce qui contribue à un travail pratique avec cet outil. L'analyseur aide à écrire un code correct et optimisé pour les systèmes 64 bits.

9. Test Parasoft C++

Un outil spécialisé pour Windows qui vous permet d'automatiser l'analyse de la qualité du code C++. Le package C++Test analyse le projet et génère du code pour tester les composants contenus dans le projet. Le package C++Test effectue un travail très important d'analyse des classes C++. Une fois le projet chargé, il est nécessaire de mettre en place des méthodes de test. Le logiciel examine chaque argument de méthode et renvoie les types de valeur correspondants. Pour ces types simples, les valeurs d'argument par défaut sont remplacées ; vous pouvez définir des données de test pour des types et des classes définis par l'utilisateur. Il est possible de remplacer les arguments C++Test par défaut et de renvoyer les valeurs obtenues à partir du test. Il convient de noter en particulier la capacité de C++Test à tester du code inachevé. Le logiciel génère un code stub pour toute méthode et fonction qui n'existe pas déjà. La simulation d'appareils externes et d'entrées définies par l'utilisateur est prise en charge. Les deux fonctions peuvent être testées à nouveau. Après avoir défini les paramètres de test pour toutes les méthodes, le package C++Test est prêt à exécuter le code exécutable. Le package génère du code de test en appelant le compilateur Visual C++ pour le préparer. Il est possible de générer des tests au niveau méthode, classe, fichier et projet.

10. Couverture

Les outils sont utilisés pour identifier et corriger les défauts de sécurité et de qualité dans les applications critiques. La technologie de Coverity supprime les obstacles à l'écriture et au déploiement de logiciels complexes en automatisant la découverte et la correction des bogues critiques et des failles de sécurité au cours du processus de développement. L'outil de Coverity est capable de traiter des dizaines de millions de lignes de code avec une erreur positive minimale, offrant une couverture de trace à 100 %.

11.KlocTravail K7

Les produits de la société sont conçus pour l'analyse automatisée du code statique, la détection et la prévention des défauts logiciels et des problèmes de sécurité. Les outils de la société servent à identifier les causes profondes des défauts de qualité et de sécurité des logiciels, et à suivre et prévenir ces défauts tout au long du processus de développement.

12 Frama-C

Un ensemble ouvert et intégré d'outils pour analyser le code source C. L'ensemble comprend ACSL (ANSI/ISO C Specification Language) - un langage spécial qui vous permet de décrire en détail les spécifications des fonctions C, par exemple, de spécifier la plage de valeurs d'entrée valides de la fonction et la plage de sortie normale valeurs.

Cette boîte à outils permet d'effectuer les actions suivantes :

  • Effectuer des vérifications formelles du code ;
  • Recherchez les erreurs d'exécution potentielles ;
  • Effectuer un audit ou un examen du code ;
  • Réaliser l'ingénierie inverse du code pour améliorer la compréhension de la structure ;
  • Générer une documentation formelle.

13. Code Surfeur

Un outil d'analyse de programme qui n'est pas directement conçu pour trouver des bogues de vulnérabilité de sécurité. Ses principaux avantages sont :

  • analyse de pointeur ;
  • Diverses analyses de flux de données (utilisation et définition des variables, dépendance des données, construction du graphe d'appels) ;
  • Langage de script.

CodeSurfer peut être utilisé pour trouver des erreurs dans le code source, pour améliorer la compréhension du code source et pour désosser les programmes. Dans le cadre de l'environnement CodeSurfer, un prototype d'outil de détection des failles de sécurité a été développé, mais l'outil développé n'est utilisé qu'au sein de l'organisation des développeurs.

14. FxCop

Fournit un moyen de valider automatiquement les assemblys .NET par rapport aux directives de conception de Microsoft .NET Framework. Le code compilé est vérifié à l'aide de mécanismes de réflexion, d'analyse MSIL et d'analyse de graphe d'appel. De ce fait, FxCop est capable de détecter plus de 200 failles (ou erreurs) dans les domaines suivants :

  • Architecture de la bibliothèque ;
  • Localisation;
  • Règles de nommage ;
  • Performance;
  • Sécurité.

FxCop offre la possibilité de créer vos propres règles à l'aide d'un SDK spécial. FxCop peut fonctionner à la fois dans l'interface graphique et sur la ligne de commande.

15.JavaChecker

Il s'agit d'un analyseur de programmes Java statique basé sur la technologie TermWare.

Cet outil vous permet d'identifier les défauts de code, tels que :

  • gestion des exceptions bâclée (blocs catch vides, exceptions génériques, etc.);
  • masquer les noms (par exemple, lorsque le nom d'un membre de classe est le même que le nom d'un paramètre de méthode formelle) ;
  • violations de style (vous pouvez définir le style de programmation à l'aide d'un ensemble d'expressions régulières) ;
  • violations des contrats d'utilisation standard (par exemple, lorsque la méthode equals est remplacée, mais pas hashCode) ;
  • violations de synchronisation (par exemple, lorsque l'accès à une variable synchronisée se fait en dehors d'un bloc synchronisé).

L'ensemble de vérifications peut être contrôlé à l'aide de commentaires de contrôle.

JavaChecker peut être appelé à partir d'un script ANT.

16 Simiens

Analyseur de similarité qui recherche la syntaxe répétitive dans plusieurs fichiers en même temps. Le programme comprend la syntaxe de divers langages de programmation, notamment C#, T-SQL, JavaScript et Visual BasicR, et peut également rechercher des fragments répétitifs dans des fichiers texte. De nombreuses options de personnalisation vous permettent d'affiner les règles de recherche de code en double. Par exemple, le paramètre de seuil (threshold) détermine le nombre de lignes de code répétées à considérer comme doublon.

Simian est un petit outil conçu pour trouver efficacement les répétitions de code. Il n'a pas d'interface graphique, mais il peut être exécuté à partir de la ligne de commande ou accessible par programme. Les résultats sont affichés sous forme de texte et peuvent être présentés dans l'un des formats intégrés (par exemple, XML). Bien que l'interface clairsemée de Simian et les capacités de sortie limitées nécessitent une certaine courbe d'apprentissage, cela aide à maintenir l'intégrité et l'efficacité du produit. Simian convient à la recherche de code en double dans les grands et les petits projets.

Le code répétitif réduit la maintenabilité et l'évolutivité du projet. Vous pouvez utiliser Simian pour trouver rapidement des extraits de code en double dans de nombreux fichiers en même temps. Puisque Simian peut être exécuté à partir de la ligne de commande, il peut être inclus dans le processus de construction pour recevoir des avertissements ou arrêter le processus en cas de répétitions de code.

Conclusion

Ainsi, dans cet article, des analyseurs statiques du code source ont été considérés, qui sont des outils auxiliaires pour le programmeur. Tous les outils sont différents et aident à suivre les classes les plus diverses de vulnérabilités de sécurité dans les programmes. On peut conclure que les analyseurs statiques doivent être précis et sensibles. Mais, malheureusement, les outils de débogage statiques ne peuvent pas donner un résultat absolument fiable.



Vous avez aimé l'article ? Partagez-le