Un problème majeur international
Une mauvaise gestion de la qualité logicielle peut induire des coûts qui deviennent exorbitants. Les cas les plus évidents sont ceux liés à la sécurité : malveillances, interruptions de service ou vols sont commis régulièrement. La tolérance aux fautes et la stabilité sont eux aussi des éléments de qualité mesurables et fréquemment prouvables . Symantec a publié fin février 2010 un sondage réalisé dans 27 pays auprès de 2 100 directeurs informatiques et responsables de la sécurité dans de petites, moyennes et grandes entreprises. Ceci correspond à un indice de confiance supérieur à 96% . Il apparaît que 75% des compagnies disent avoir subi des attaques dans leurs systèmes informatiques. Pour les résultats français, ce chiffre est de 73%, dont 40% sont qualifiées d’« assez ou très nuisibles» . 29% affirment que la fréquence des attaques augmente depuis les 12 derniers mois. Rocky Heckman, architecte sécurité chez Microsoft a déclaré que le site Microsoft.com est la cible de 7000 à 9000 attaques depuis internet par secondes en moyenne.
Les conséquences majeures sont :
– Une perte de productivité (36%),
– Un manque à gagner (33%),
– Une perte de confiance des clients (32%).
Les coûts moyens du cybercrime pour l’année 2009 rapportés auprès des entreprises interrogées sont de 2 millions de dollars US. Pour les plus grandes, il s’agit d’environ 3 millions de dollars US. Selon une étude [Ins10] ArcSight/Ponemon auprès de 45 organisations de 500 à 105000 employés, ce chiffre est de 3,8 millions de dollars US par an, via en moyenne une attaque réussie par semaine. Une troisème étude de CA Technologies pour l’année 2010 montre que l’Europe est assez concernée par ce phénomène. Le fait que les entreprises françaises soient en tête des victimes ne montre pas uniquement qu’elle possèdent une activité économique importante sur internet mais également qu’elles sont mal préparées et défendues contre cette menace. Ces pertes sont généralement équitablement dues à :
– la corruption d’information,
– le déni de service par congestion du système,
– le vol de propriété intellectuelle.
L’utilisation frauduleuse des moyens de paiement récupérés qui causent également directement des vols auprès des clients ne sont pas comptés. Les attaques peuvent aussi être à but politique ou belligérantes (« cyberterrorisme »). Le général Keith Alexander, responsable de la cyber-sécurité (US Cyber command) des États-Unis, a annoncé que le réseau du Pentagone est attaqué six millions de fois par jour, soit environ 70 attaques par secondes. Plusieurs portails Web de partis politiques sont régulièrement défacés ou redirigés par des « hacktivistes ». Les défauts de conception et les anomalies de développement ont un coût pour le projet qui augmente en fonction du moment de leur découverte.Il est donc impératif d’être en mesure de détecter ces problèmes de codages au plus tôt dans le cycle de développement.
Sources des problèmes à corriger dans un programme informatique
Lors de la rédaction d’un code, diverses causes qui sont exposées ici sont à l’origine de l’introduction de motifs indésirables. Cette section présente et précise les notions de « règles » et de « métriques » dans le contexte de l’analyse statique de code. Ce sont ces éléments qui permettent de contrôler le respect de conventions, le design et l’optimisation du code, ainsi que l’application de mesures de sécurité.
Permissivité de la syntaxe
Comme chaque langue naturelle, chaque langage de programmation possède sa propre syntaxe pour être correctement compris par l’homme et la machine. Ces syntaxes sont toujours plus ou moins permissives et introduisent des libertés dans la rédaction du code. Ainsi un programme comportant la même suite d’instructions ou les mêmes fonctions peut s’écrire de différentes façons. Le cas le plus évident est la présentation du code, par l’usage d’un nombre précis d’espaces entre les instructions pour indenter le code ainsi que la position des retours à la ligne. Ces libertés ont donné naissance à des conventions d’écriture et de présentation afin d’homogénéiser la production de code et d’en faciliter la lecture.
Mauvais design
Un code peut s’avérer difficilement compréhensible et faiblement évolutif à cause d’une mauvaise conception, d’une architecture mal pensée. Un volume de code trop inégalement réparti révèle que les fonctions des classes ont été mal distribuées. Un manque d’abstraction du code par manque d’interfaces et peu d’héritage empêche l’application d’intégrer de nouvelles fonctionnalités, de nouveaux modules, ou d’interchanger des éléments internes facilement. Une autre conséquence possible d’une architecture mal maîtrisée est l’apparition de failles de sécurité. Un mauvais design se perçoit dans les outils d’analyse par l’intermédiaire de calculs statistiques. Par exemple la complexité cyclomatique d’une méthode est un calcul qui prend en compte ses branchements et qui permet d’indiquer si elle est trop chargée. Une correction possible est alors d’extraire des sous-ensembles pour créer d’autres méthodes. Les rapports et la répartition entre les classes abstraites et les classes concrètes sont également des indices importants.
Evolutions
Le domaine de l’informatique est connu pour être un secteur très dynamique et innovant, jouissant d’importants moyens dédiés à la recherche et au développement. Le langage utilisé ainsi que le contexte d’utilisation d’un code sont par conséquent des éléments soumis à une constante évolution. De plus, les restructurations et les changements de stratégie de l’entreprise impactent souvent les besoins spécifiés aux applications métier. Il est fréquent que plusieurs équipes avec des compétences et des pratiques différentes soient amenées à travailler sur une même application. Ces changements induisent des adaptations régulières à apporter au code pour le maintenir évolutif, homogène et compétitif.
Règles et métriques
Pour contrôler l’apparition de défauts et s’assurer que les bonnes pratiques de codage sont appliquées sont définies des règles et des métriques. Une règle décrit une pratique de codage à respecter. Elle permet de détecter les éléments du code qui seront appelés à être transformés par une opération de refactoring . D’après Macaigne [MAC11] une règle est une : « Méthode, recommandation résultant d’une étude ou de l’expérience et applicable dans un domaine donné pour atteindre une certaine fin. » Sa formulation est très généralement un modèle recherché dans le code par pattern matching (cf 4.1.6) en contrôlant un contexte et des conditions d’application spécifiques. Parmi les outils d’audit de code existants, il n’existe pas de standard de base de règles qui serait uniquement l’application stricte de certaines normes. Elles sont souvent le fruit de divers contributeurs et se constituent de manière incrémentale. Un exemple de règle est : « Pas de bloc « catch » vide (AvoidEmptyCatchStatement). » .
Le modèle correspondant devra détecter tout bloc de code de type « catch » n’ayant aucune instruction. Sa définition dépend donc fortement du choix de représentation du code qui sera utilisé pour l’appliquer. Les outils d’analyse statique travaillent généralement avec un ensemble de règles appelé référentiel. Certaines règles s’appuient sur des métriques. Par exemple« la complexité cyclomatique d’une méthode ne doit pas dépasser 10 » implique l’appel d’une métrique qui va mesurer cette complexité. Une métrique est un couple (f ;E) où f est une fonction déduite par analyse du code source généralement numérique et E est une échelle de comparaison. Les métriques sont des indicateurs permettant d’obtenir un « état de santé » global d’un projet en mettant en évidence des défauts dans la rédaction du code (peu évolutif, mal réparti,. . .). Il existe de nombreuses métriques pour déterminer si une partie de code est de bonne qualité. Un rapport technique sur les métriques employées pour un projet orienté objet a été présenté par R. Abounader and David A. Lamb [AL97]. Par exemple la complexité cyclomatique estime la complexité d’un code en fonction du nombre de branchements qu’il effectue. Comme autre facteur trivial, on peut considérer la qualité documentaire par le calcul du ratio des lignes de commentaires par rapport aux lignes de codes. Un indice de couplage entre les objets est aussi utile pour assurer une répartition pertinente du code.
|
Table des matières
1 Introduction
1.1 Problématique
1.2 Objectifs de la thèse
1.3 Organisation du document
2 Qualité logicielle
2.1 Un problème majeur international
2.2 Sources des problèmes à corriger dans un programme informatique
2.2.1 Permissivité de la syntaxe
2.2.2 Mauvaises pratiques
2.2.3 Mauvais design
2.2.4 Evolutions
2.3 Règles et métriques
2.4 La sécurité : un critère qualitatif
2.4.1 MITRE
2.4.2 OWASP
2.4.3 JAVASEC
2.5 Conclusion
3 Le langage Java et ses utilisations
3.1 Présentation du langage Java
3.1.1 Principe
3.1.2 Les mécanismes de sécurité du langage
3.1.2.1 Critères de sécurité dans le cadre des applications Web
3.1.2.2 Propriétés et éléments supportés par le langage
3.1.3 Caractéristiques des méthodes Java
3.1.3.1 Signature
3.1.3.2 Périmètre d’influence
3.1.4 Propriétés obstacles aux analyses
3.1.4.1 Réflexivité et Comportements dynamiques
3.1.4.2 Code natif
3.1.5 Synthèse
3.2 Description des applications Java
3.2.1 Côté client et serveur
3.2.1.1 Point d’entrée d’une application
3.2.1.2 Les bibliothèques
3.2.1.3 Les Beans
3.2.2 Côté client
3.2.2.1 Les Applets
3.2.2.2 Les Midlets
3.2.3 Côté serveur
3.2.3.1 Les Servlets
3.2.3.2 Les Server Side Includes (SSI)
3.2.3.3 Les Enterprise Java Beans (EJB)
3.2.3.4 Les Java Server Pages (JSP)
3.2.3.5 Les Portlets (JSR 168)
3.2.3.6 Les Aglets
3.2.4 Langages, frameworks et API des applications Web
3.2.4.1 Applications sécurisées
3.2.4.2 APIs de communication
3.2.5 Contenu et packaging des applications
3.2.5.1 JAR/JAM
3.2.5.2 WAR
3.2.5.3 EAR
3.2.5.4 JNLP
3.2.5.5 CAB, ZIP
3.2.6 Synthèse
4 Techniques d’analyse et outils pour le langage Java
4.1 Techniques d’analyse
4.1.1 Analyse statique versus dynamique
4.1.2 Le Model checking
4.1.3 L’interprétation abstraite
4.1.4 Le Program Slicing
4.1.5 Teinte de variable
4.1.6 La recherche de motifs de code (pattern matching)
4.1.6.1 Nature des motifs de code
4.1.6.2 Exemple
4.1.7 Faux négatifs et faux positifs : un double compromis
4.1.7.1 Biais-variance
4.1.7.2 Incertitudes
4.1.7.3 Limites liées à la faculté de généricité
4.1.8 Barrières du langage
4.1.9 Synthèse et conclusion
4.2 Outils d’analyse (audit) de code Java
4.3 Le refactoring de code
4.3.1 But du refactoring
4.3.2 Impact du refactoring
4.3.3 Mise en oeuvre du refactoring
4.3.4 Synthèse
4.4 Outils de refactoring de code Java
4.5 Synthèse
5 Sécurité applicative
6 Conclusion