• Aucun résultat trouvé

L’analyse statique est un moyen de vérification automatique permettant de prédire les compor-tements d’un programme lors de son exécution sans réellement l’exécuter. Elle est généralement utilisée dans le débogage, en particulier pour la recherche d’erreurs pouvant apparaître à l’exé-cution. Il s’agit de la technique la plus adéquate pour analyser des applications dédiées à des plateformes à ressources réduites telles que les cartes à puce où une analyse dynamique serait très coûteuse.

L’analyse statique consiste généralement à explorer les différents chemins d’exécution possibles d’un programme. Elle se base sur la construction d’un graphe de flux de contrôle (Control flow graph, CFG) qui est une représentation par un graphe de tous les chemins qui peuvent être traversés dans un programme durant son exécution. Les nœuds du graphe représentent les blocs d’instruc-tions de base qui sont toujours exécutées sans interruption et les arêtes représentent les flux de contrôle qui relient deux blocs différents. Un graphe d’appels représente potentiellement un flux de contrôle inter-méthodes. Les nœuds d’un graphe d’appels correspondent aux méthodes et une arête représente une méthode qui invoque une autre méthode.

Une analyse plus élaborée inclut également un contrôle des flux de données échangés entre des méthodes ou des applications. Elle permet d’avoir des informations sur l’ensemble des données pouvant apparaitre en un certain point du programme. Elle est généralement utilisée afin de détecter

des objets non référencés dans le programme ou de vérifier que certains objets sensibles ne sont pas utilisés dans un contexte non-prévu ou non-sécurisé.

Il existe différentes techniques d’analyse statique, la plus répandue consistant à définir des motifs correspondant à une vulnérabilité ou des erreurs liées à un langage de programmation et de rechercher ces motifs dans le code. D’autres analyses plus élaborées sont basées sur l’analyse des flux de données et des flux de contrôle. Enfin, il existe des outils qui nécessitent d’ajouter des annotations dans le code pour spécifier une règle à vérifier.

4.2.1 État de l’art des outils d’analyse statique

Plusieurs recherches se sont intéressées à la vérification de programmes Java. Certaines se situent dans la catégorie des outils qui fournissent des informations syntaxiques concernant des règles stylistiques d’écriture de programmes [Che]. D’autres avertissent de l’usage de constructions considérées comme dangereuses ou interdites par des règles visant à une programmation plus «sûre».

Nous nous intéressons à cette deuxième catégorie d’outils.

Wagner et al. [SJCP05] présentent une comparaison entre un ensemble de ces outils, dont Findbugs [HP04], PMD [PMD], QJ PRO [QJP] et quelques projets industriels (non cités). Leur étude se base sur la quantification des « faux positifs » générés par chaque outil. Dans [RAF04], le nombre de « faux négatifs» est aussi pris en compte. Ces deux comparaisons ont conclu que chaque outil est en mesure de détecter des bogues que les autres ne détectent pas, et par conséquent la combinaison de ces différents résultats permettrait d’avoir une analyse plus complète. Cependant, certains de ces outils comme Findbugs sont évolutifs. Ils utilisent des modules complémentaires, chacun étant en charge de vérifier une propriété. Dans nos travaux nous avons sélectionné l’outil d’analyse Findbugs, nos critères de sélection étant basés sur :

– l’analyse de flux de données : afin de suivre la propagation des données douteuses dans le code ;

– l’extensibilité : permettant d’ajouter facilement des modules pour adapter l’outil à notre besoin de détecter des attaques Web XSS ;

– le logiciel libre (Open source) qui permet d’apporter des ajouts et modifications.

Dans la suite nous présentons quelques exemples de logiciels d’analyse statique, open source, notamment l’outil Findbugs :

JLint. JLint [Kon] est un outil d’analyse de bytecode Java qui effectue des contrôles syntaxiques, une analyse de flux de données et une analyse inter-procédurale des programmes à multi-tâches.

Il contient un composant appelé AntiC, qui est un vérificateur de syntaxe pour les langages de la famille du langage C, à savoir : C/C++, objectiveC et le langage Java. Cependant, JLint ne permet pas l’analyser des servlets ce qui est contraignant dans notre cas d’étude, puisque nous nous intéressons à la sécurité des applications Web Java Card 3 (basées sur des servlets). De plus, cet outil n’offre pas de mécanisme d’intégration de plugins (modules additionnels). Pour ajouter une nouvelle propriété d’analyse, il est nécessaire de modifier le code source et de développer les méthodes de test supplémentaires en langage C.

PMD. PMD [PMD] permet d’analyser du code source Java. Il est basé sur la définition d’un ensemble de règles à rechercher dans un code. Un ensemble de règles est fourni par défaut dans l’outil, à savoir :

– absence d’un des états try / catch / finally ;

– les variables locales, les paramètres et les méthodes privées non utilisées ; – les objets qui ne sont pas nécessaires ;

– les expressions trop compliquées - inutiles si les déclarations, les boucles for qui pourraient être des boucles while ;

– la duplication de code.

L’outil est extensible, permettant de développer de nouvelles règles à inclure dans l’analyse.

Toutefois le développement de ces règles nécessite des connaissances en Arbre syntaxique abstrait (Abstract Syntax Tree, AST) sur lequel PMD se base.

Findbugs : Findbugs [Fin] est un logiciel, distribué dans les termes d’une licence LGPL et déve-loppé à l’université du Maryland, Etats-Unis. Il permet de détecter des bogues dans un programme Java, à partir de l’analyse du bytecode à la recherche de certains motifs.

Findbugsinclut un ensemble important de détecteurs permettant de déceler des bogues généra-lement liés à des défauts de programmation. Cependant, l’outil est extensible offrant la possibilité de rajouter des plugins pour vérifier des propriétés supplémentaires. L’utilisateur peut limiter son analyse à uniquement des propriétés qu’il souhaite vérifier en sélectionnant les détecteurs qui l’in-téressent.

Une synthèse effectuée dans [LL05] compare un ensemble d’outils d’analyse statique et classe l’analyseurFinbugscomme l’outil le plus facilement extensible qui offre la possibilité d’ajouter un plugin pour vérifier une propriété de sécurité additionnelle. Dans [IBM], un développeur d’IBM décrit en détail comment développer un nouveau plugin.

Un plugin est une archive au format « jar » qui peut comporter un ou plusieurs détecteurs.

Les détecteurs sont basés sur le patronVisitor. Ils implémentent l’interfaceDetectorqui inclut la méthodevisitclassContext()qui invoque chaque classe de l’application. Le logiciel utilise la librairie BCEL (Byte Code Engineering Library) qui est une librairie Java permettant d’analyser et de manipuler des fichiers « class » Java et d’obtenir des informations élémentaires sur tous les objets et méthodes contenus dans ces fichiers (méthodes, attributs, instructions, etc).

Findbugs propose un ensemble de classes et d’interfaces qui peuvent être étendues pour le dé-veloppement d’un nouveau plugin. Dans notre cas, nous avons exploité la classeOpcodeStack, qui permet de calculer une abstraction de la pile d’exécution en fonction des différentes instructions bytecode (Opcode) possibles. L’analyse des flux de données dansFindbugs tient compte de la dé-pendance causale entre les variables locales d’une méthode (analyse intra-procédurale). Cependant, cette analyse de dépendance causale se limite à une analyse méthode par méthode et ne tient pas compte des appels interméthodes d’une même classe ou de classes différentes. D’autre part, l’ana-lyse intra-procédurale est incomplète car différents cas d’Opcodene sont pas complètement traités, notamment dans le cas des tableaux et des vecteurs (aaload, aastore, ...).

4.2.2 L’analyse statique dans Java Card

Les applets Java Card sont des applications destinées à être utilisées dans des domaines assez sensibles comme dans les cartes bancaires. De ce fait, différentes recherches se sont intéressées à la vérification de ce type d’applications. Compte tenu des ressources limitées des plateformes (cartes à puces, système embarqués, . . . ) qui hébergent ces applets, la plupart des recherches se sont basées sur l’analyse et la vérification des applications avant d’être chargées dans la carte (off-Card). Parmi ces outils, de nombreux travaux comme Jack [BRlLV03], Loop [JB01], ou encore les travaux de Gemplus présentés dans [CnH02], se basent sur la vérification formelle et utilisent le langage JML (Java Modeling Langage) pour la définition d’une spécification de l’ensemble des classes et interfaces de l’application. JML (Java Modeling Language) est un langage de spécification d’un comportement. Il permet de définir l’usage correct de l’ensemble des applications (interface syntaxique du code, signature des méthodes, types des attributs, etc.) se basant sur la définition des pré et post-conditions ainsi que des invariants. Les spécifications sont ajoutées dans une application Java ou Java Card sous forme d’annotations Java. Cependant, ce type d’outils demande un effort considérable de la part du développeur qui doit lui-même définir la spécification correspondante à l’application qu’il souhaite analyser.

Dans [PJM+00, JL00], les auteurs présentent le projet PACap, dont l’objectif est de vérifier les interactions entre des applets Java Card, et de certifier qu’une nouvelle applet interagit de manière sécurisée avec des applets préalablement chargées dans la carte. L’outil proposé vérifie les flux de données entre des objets de la carte à puce par une analyse statique. Il contrôle si une application est correctement implémentée respectant une politique de sécurité qui définit les niveaux de partage autorisés. Cependant, l’outil ne peut pas détecter d’autres violations que celles définies dans la politique de sécurité.

Loizidis et al. [ALK+08] présentent un outil d’analyse statique automatique basé sur plusieurs détecteurs qui étendent l’analyseur Findbugs, pour vérifier trois types de violations. Le premier détecteur est permet de verifier le respect des restrictions relatives aux communications inter-applets via une interface de partage. Il construit un CFG pour toutes les classes d’une applet afin de détecter les violations de propriétés inter-procédurales, telles que des appels récursifs à une méthode déclarée dans les interfaces de partage. Le second détecteur vérifie que les appels à des méthodes d’API ne provoquent pas d’exception non gérée, qui pourrait conduire à quitter l’applet dans un état imprévisible. Le troisième permet d’effectuer une analyse de flux de données pour vérifier les arguments d’une méthode invoquée et détecter des failles tels que des paramètres nuls ou non valides (une valeur négative pour un index dans un tableau).

Notre étude se base surFindbugs, associé à la technique de dépendance causale « tainting ».

L’objectif de notre analyse est de tracer la propagation des données dans une exécution abstraite de bytecode et de vérifier la présence de vulnérabilités à des attaques Web par injection de code dans des applications Web dédiées à des cartes à puce, en particulier les Java Card 3. Nous verrons par la suite qu’un ensemble d’améliorations dans Findbugs a été nécessaire afin de rendre notre analyse plus efficace.