• Aucun résultat trouvé

2.6 Mécanismes de sécurité

2.6.3 Analyse statique

Cette technique opère avant l’exécution. A partir de l’analyse du code du programme, elle décide en un temps fini, si le programme satisfait la propriété ou pas. Par conséquent, seuls les programmes acceptés par l’analyse sont autorisés à être exécutés. Il y a de nombreux systèmes dans lesquels on ne peut prendre le risque d’exécuter des programmes, sans avoir à assurer préalablement la correction de leur comportement vis-à-vis de certaines propriétés de sécurité cruciales. On rencontre ce genre de systèmes dans les applications critiques telles que les réacteurs nucléaires, les lancements de fusées, etc. Pour cela, l’analyse statique a été mise au point, afin d’analyser le code du programme avant son exécution sans avoir à requérir aux données réelles qu’il manipule durant l’exécution. Les méthodes d’analyse statique peuvent être réparties en trois grandes classes :

– Vérification orientée flots ; – Vérification par typage ;

– Vérification par évaluation de modèles ; – Vérification par interprétation abstraite.

Vérification orientée flots

À l’origine, cette méthode [63] a été créée pour l’optimisation et l’élimination du code mort. Elle permet d’analyser le flot de données ou d’analyser le flot de contrôle, de sorte à représenter tous les comportements du programme, sans avoir à l’exécuter. Par conséquent, il s’agit d’abstraire le programme. L’analyse orientée flot de contrôle permet de suivre le flot d’exécution du programme, en retraçant toutes les interactions possibles entre les blocs d’ins- tructions. Tandis que l’analyse du flot de données permet d’identifier le flot d’information à un point précis du programme, ainsi que de suivre le déplacement de toutes les données que se soit à l’intérieur du programme où vers les autres programmes qui lui sont connectés.

Vérification par typage

Au départ, cette technique [82] a été mise au point pour garantir que toutes les valeurs affectées aux variables d’un programme sont conformes à leur type. Par la suite, elle a été étendue pour inférer les effets d’une construnction syntaxique. Dans le contexte de sécu- rité et de mécanisme de sécurité, les programmes sont dits corrects s’ils sont bien typés par rapport à une propriété donnée. Cela est très bien exprimé, dans la citation de Robin Mil- ner “Well-typed programs do not go wrong”. Par conséquent, cette analyse doit établir une approximation statique du comportement du programme vis à vis de la propriété à assurer. L’analyse basée type repose sur trois éléments fondamentaux :

(1) La sémantique statique qui permet de spécifier les règles de typage. (2) La sémantique dynamique qui spécifie les règles d’évaluation.

(3) L’algorithme d’inférence qui est utilisé pour montrer qu’un programme est bien typé.

Vérification par évaluation de modèles

La vérification orientée modèle dite plus communément “Model Checking” [81] consiste à vérifier si un modèle représentant un programme satisfait une spécification donnée (la pro- priété). Par conséquent, au lieu de raisonner sur le programme lui-même, on raisonne sur le modèle qui le représente. Ce modèle est généralement exprimé par un graphe orienté constitué de nœuds et d’arcs. Un ensemble de propositions atomiques est associé à chaque nœud. Ces nœuds représentent les états d’un programme, les arcs représente les exécutions qui changent ces états, et les propositions atomiques désignent les propriétés de base caractérisant un point

spécifique de l’exécution. Généralement, le langage de spécification le plus utilisé, dans ce type de vérification est la logique temporelle. Le problème est exprimé formellement comme suit : “Étant donné une formule de la logique temporelle p et un modèle M avec un état initial s, il s’agit de décider si M,s satisfait p".

Vérification par interprétation abstraite

L’analyse par interprétation abstraite [28] consiste à prévoir le comportement d’un pro- gramme, avant son exécution, en remplaçant les valeurs réelles qui seront utilisées, par des valeurs abstraites dites non standards. Ces dernières sont nettement plus faciles à manipuler lors de la vérification d’une propriété de sécurité donnée. La vérification par interprétation abstraite est constituée de quatre phases :

– La définition d’une sémantique formelle ou concrète du langage ;

– La définition d’une sémantique abstraite ou non standard qui est fortement liée à la propriété que l’on désire vérifier. Cette phase permet d’optimiser l’information utile, en supprimant tout ce qui est obsolète à l’analyse ;

– La définition d’une fonction d’abstraction qui substitue les valeurs abstraites aux va- leurs concrètes ;

– La définition d’une fonction de concrétisation qui convertit une valeur abstraite vers une valeur concrète.

Nous présentons dans ce qui suit deux exemples de mécanismes de sécurité appartenant à la classe d’analyse statique. Les mécanismes de sécurité relatifs au monitorage d’exécution et à la réécriture de programmes seront quant à eux abordés en détail, dans le prochain chapitre.

TAL (Typed Assembly Language)

Ce travail [84] a été mené à l’université de Cornell, il appartient à la gamme d’outils de vérification statique. Il permet de garantir qu’avant l’exécution, un programme satisfait quelques spécifications. Son principe majeur repose sur le fait que si le typage des variables est bien conservé alors le programme généré est sûr.

bleur qui est traditionnellement non typé. Cette extension inclut : des annotations de type, des primitives de gestion de mémoire, et un ensemble correct de règles de typage. Ces règles de typage garantissent la sûreté de la mémoire, la sûreté du flot de contrôle, et enfin la sûreté des types des programmes écrits en TAL. Par conséquent, ces règles de typage fournissent l’assurance que le programme utilise correctement ses variables, et ce, contrairement à l’as- sembleur classique qui comporte uniquement des valeurs non typées ; dans lequel une erreur de programmation, ou un code malicieux peuvent provoquer une faille importante de sécu- rité. Aussi, TAL possède un atout intéressant, c’est le fait que les constructions de typage lui offrent une grande expressivité lui permettant de représenter : les enregistrements, les tableaux, les fonctions polymorphiques, les exceptions, les types de données abstraites, le sous-typage, et les modules, cela rend TAL assez souple pour supporter un grand nombre d’optimisations destinées aux compilateurs bas niveau. Par conséquent, TAL constitue une plateforme idéale pour les compilateurs orientés-type qui visent à générer du code sûr véri- fiable. Ce code peut par la suite être utilisé dans les applications à code mobile sécurisé ou pour les noyaux des systèmes d’exploitation extensibles. TALx86 est une variante de TAL qui a été implémentée pour l’architecture Intel’s IA32. Pour cela, un compilateur a été mis au point, afin de produire un code assembleur annoté à partir d’un code source écrit en Popcorn (un sous ensemble du langage C).

PCC (Proof-Carrying Code )

“Faire la preuve qu’un programme est correct c’est comme trouver la sortie d’un laby- rinthe. Une fois que quelqu’un l’a trouvé, il peut donner la séquence des mouvements aux autres, qui sortiront alors bien plus facilement. À condition que les indications soient cor- rectes ...” ceci est l’intuition sur laquelle repose le PCC [85]. En d’autres termes, vérifier une preuve est beaucoup plus simple que de la trouver.

Le PCC (“Proof-Carrying Code” ou code portant la preuve) est un mécanisme de sécurité statique permettant à un producteur de code de convaincre un consommateur (un utilisateur) qui ne lui fait pas “forcément” confiance que son code est sûr, dans le sens où il respecte la po- litique de sécurité désirée par le consommateur. Pour gagner la confiance du consommateur, le producteur doit associer au code “potentiellement malicieux” qu’il envoie au consomma- teur une preuve formelle démontrant que ce code respecte la politique de sécurité en ques- tion. Ainsi, le consommateur n’aura qu’à vérifier la validité de cette preuve d’une façon très simple, en utilisant un vérificateur de preuves. Une fois que cette vérification s’avère posi- tive, le code peut être exécuté, en toute sécurité, autant de fois que le consommateur le désire, sans avoir besoin de refaire la vérification. L’approche générale de PCC est présentée dans la figure2.8. Par conséquent, l’approche PCC possède plusieurs avantages :

FIGURE 2.8 – Approche générale de l’application de la sécurité en se basant sur la certifica- tion de programmes.

– Les preuves sont facilement et rapidement vérifiables ;

– Il n’est pas nécessaire de crypter les données ou d’avoir une certaine confiance entre les deux côtés, vu que PCC permet de garantir la sûreté d’un code quelque soit le des- tinataire ;

– PCC n’engendre aucun coût, durant l’exécution du moment que la preuve est générée statiquement.

Néanmoins, PCC engendre les deux inconvénients suivants :

– Du côté producteur la conception de la preuve est très fastidieuse et assez complexe même pour des petits programmes ;

– La taille de la preuve est assez importante, elle dépasse souvent la taille du code lui- même.