• Aucun résultat trouvé

Principes de conception s´ecuris´ee

2.2 S´ ecurit´ e

2.2.2 Principes de conception s´ecuris´ee

Nous voyons maintenant les diff´erents principes pour la conception de syst`emes pour la protection de l’information. Comme nous l’avons dit pr´ec´edemment, les objectifs de s´ecurit´e de l’information et d’isolation sont ´eminemment proches, et la structure des syst`emes pour assurer ces buts le sont ´egalement. On peut citer par exemple l’usage de TCB, utilis´es pour la s´ecurit´e, qui peut ˆetre ´etendu pour prouver diff´erentes autres propri´et´es n´egatives (e.g. de sˆuret´e de fonctionnement) [Rus89] ; l’usage de syst`emes `a capacit´es pour faire de la tol´erance aux fautes [Den76] ; les correspondances entre l’architecture IMA a´eronautique et l’architecture de s´ecurit´e MILS [BDRS08]...

Int´erˆet des principes de s´ecurit´e Ecrire des programmes sans faille de s´ecurit´e,´ tout comme sans bugs, est une tˆache tr`es difficile ; surtout pour un syst`eme d’ex- ploitation, par nature de bas niveau et expos´e `a toute la complexit´e du mat´eriel. Les failles de s´ecurit´e sont des bugs particuli`erement difficiles `a d´etecter : alors que les bugs ordinaires causent des dysfonctionnements quand le programme est utilis´e en condition normale, les failles de s´ecurit´e n’apparaissent souvent que lorsque le programme est “mal utilis´e” par intention. Il est donc difficile de trouver des failles de s´ecurit´e par test. De plus, mˆeme si on arrivait `a ´ecrire un programme sans bug, cela ne signifie par pour autant que le syst`eme est sˆur de fonctionnement [Den76, p.

14

Notons que cela est possible car le syst`eme d’exploitation contrˆole l’ensemble des tˆaches, i.e. le syst`eme est « ferm´e ». Cette approche n’est pas suffisante pour prot´eger la disponibilit´e de l’information dans un serveur de donn´ees branch´e sur un r´eseau ouvert comme Internet, par exemple.

2.2.2. Principes de conception s´ecuris´ee

361] : une faute peut par exemple r´esulter d’une d´efaillance mat´erielle. Ce qu’il faut, c’est structurer le syst`eme afin d’ˆetre par´e au mieux `a l’´eventualit´e d’une erreur.

Pour aider cette tˆache, un ensemble de “bonnes pratiques” `a suivre est le meilleur outil dont on dispose. Ces pratiques visent `a structurer le syst`eme et `a se focaliser sur les endroits importants. Cela permet de r´eduire `a la fois le nombre de failles et la port´ee de ces failles. Dans cette section, nous pr´esentons les principes de s´ecurit´e de base, rassembl´es par Saltzer et Schroeder [SS74]. Nous reformulons leur explication en d´efinissant des notions qui s’y rapportent au fur et `a mesure, et nous compl´etons ces principes par des d´eveloppements ou interpr´etations post´erieures.

2.2.2.1 S´eparation des privil`eges

Un privil`ege est la possibilit´e d’accomplir une certaine action, par exemple pouvoir programmer la carte r´eseau, modifier les param`etres de s´ecurit´e du syst`eme, pouvoir ouvrir un fichier, etc.. La s´eparation des privil`eges consiste `a n’attribuer ces privil`eges qu’`a certains domaines de protection s´epar´es. Ainsi, la compromission d’un de ces domaines ne r´esulte pas en la compromission de l’ensemble du syst`eme.

Les processus UNIX ont des droits diff´erents, et impl´ementent donc la s´eparation des privil`eges. Mais certains privil`eges sont accessibles `a tout le monde (par exemple le droit de cr´eer un socket r´eseau). De plus, les privil`eges du noyau ne sont pas s´epar´es, au contraire de la structure de type micronoyau, pour laquelle les services r´eseau, ´ecran, et disque, qui ont besoin de privil`eges diff´erents (pour acc´eder aux diff´erents p´eriph´eriques), sont plac´es dans des domaines de protection s´epar´es.

2.2.2.2 M´ediation compl`ete

Un privil`ege se pr´esente sous la forme de l’autorisation d’un acc`es `a un objet ou ressource du syst`eme. Ce principe ´enonce qu’il faut syst´ematiquement v´erifier que chaque acc`es soit bien autoris´e.

Ceci se fait par un m´ecanisme appel´e contrˆole d’acc`es. `A un instant donn´e, ce m´ecanisme peut ˆetre repr´esent´e par une matrice [Lam71] repr´esentant quel domaine a quel droit sur quel objet. Il y a deux mani`eres principales de g´erer ces droits : soit on associe `a chaque objet la liste des domaines qui ont le droit d’y acc´eder (mod`ele par liste de contrˆole d’acc`es, ou ACL). Soit on associe `a chaque domaine la liste des objets auxquels il a le droit d’acc´eder (mod`ele par capacit´e). La comparaison entre ces mod`eles est ´etudi´ee en section 3.3.1. Les permissions d’acc`es de chaque domaine vers chaque objet sont r´egies par des r`egles qui forment la politique de s´ecurit´e.

Saltzer et Schroeder mettent particuli`erement en garde contre tout m´ecanisme qui conserverait une copie locale des autorisations (comme un “cache” des acc`es) : une copie mal mise `a jour permettrait des acc`es non autoris´es. Plus g´en´eralement, il y a une faille de s´ecurit´e (appel´e bug TOCTTOU [BD96], pour time of check to time of use) lorsqu’un programme v´erifie une caract´eristique sur un objet, et pr´esume que cette caract´eristique est toujours v´erifi´ee alors qu’elle a pu changer. Le sch´ema de synchronisation use/destroy que nous avons d´evelopp´e (§ 5.2.4) sert en particulier `a ´eviter ces probl`emes.

2.2.2.3 D´efaillance sˆure par d´efaut

Consiste `a interdire tout ce qui n’est pas explicitement autoris´e, plutˆot qu’autoriser tout ce qui n’est pas explicitement interdit. Autrement dit, les programmes n’ont par d´efaut acc`es `a rien, et on doit explicitement leur autoriser l’acc`es. Bien que les deux soient fonctionellement ´equivalents, le refus d’acc`es par d´efaut est plus sˆur si les permissions `a accorder `a un programme sont mal consid´er´ees : oublier de fournir un doit d’acc`es `a un programme qui en a besoin sera vite d´etect´e, tandis qu’oublier de retirer un droit d’acc`es `a un programme qui n’en a pas besoin est dangereux et ind´etectable. Denning appelle un syst`eme qui suit ce principe syst`eme ferm´e [Den76].

Les syst`emes `a capacit´es purs impl´ementent naturellement la fermeture du syst`eme. Au contraire de syst`emes comme UNIX, o`u encapsuler un programme doit se faire de mani`ere explicite (e.g. [Ber07, §5.2]), et o`u on n’est jamais sˆur que l’encapsulation soit compl`ete (e.g. au vu des nouveaux appels syst`emes r´eguli`erement ajout´es `a Linux).

2.2.2.4 Principe du moindre privil`ege (POLP)

Ce principe ´enonce que toutes les tˆaches doivent se voir accorder les privil`eges minimums n´ecessaires pour accomplir leur travail. Cela limite les dommages caus´es par une ´eventuelle compromission. Par exemple, un programme qui d´ecompresse des fichiers sur le disque n’a pas besoin de pouvoir acc´eder au r´eseau.

Ce principe est encore plus int´eressant dans le cadre d’un syst`eme ferm´e, car cela encourage `a donner une liste de privil`ege courte.

Miller et Shapiro distinguent deux notions de privil`ege, la permission et l’autorit´e [MS03]. La permission autorise un domaine `a accomplir une action directement, tandis que l’autorit´e repr´esente la possibilit´e de le faire apr`es communication avec d’autres tˆaches. Les deux doivent ˆetre minimis´ees.

2.2.2.5 Economie de m´´ ecanisme

Ce principe consiste `a garder la conception aussi simple et petite que possible. Essayer par exemple de trouver des m´ecanismes g´en´eraux plutˆot que d’accumuler les exceptions. Ce principe doit ˆetre en particulier utilis´e pour tout ce qui touche les m´ecanismes de protection ; Rushby insiste ainsi sur le besoin d’avoir un syst`eme de protection unique [Rus84, Rus89].

Garder la conception simple et claire facilite la compr´ehension du code (et donc sa revue). L’´economie de m´ecanisme permet aussi souvent d’´eliminer du code, source de bugs.

Une id´ee proche de l’´economie de m´ecanisme est celle de l’´economie de code en g´en´eral. En minimisant la taille du code, on minimise le nombre de bugs15

, donc de failles [Ber07]. Les id´ees sont proches, car en g´en´eral une conception simple engendre une impl´ementation simple, ou en tout cas avec peu de lignes de code.

15

ce d’autant plus que le ration bug/nombre de lignes de code augmente avec la taille du programme [Lip82] : intuitivement quand le programme est petit, on peut en comprendre tous les aspects simultan´ement, ce qui ´elimine tous les bugs d’« interfa¸cage »

2.2.2. Principes de conception s´ecuris´ee

Ce n’est cependant pas toujours le cas ; mais nous estimons qu’il faut toujours pr´ef´erer une conception simple, mˆeme au prix d’une impl´ementation localement complexe. Par exemple, une biblioth`eque permettant l’acc`es parall`ele `a des structures de donn´ees parall`eles de mani`ere lock-free (comme dans [Fra04]), sera plus simple `a utiliser mais d’impl´ementation beaucoup plus compliqu´ee, qu’une biblioth`eque dont l’impl´ementation est bas´ee sur les locks.

2.2.2.6 Minimisation des m´ecanismes communs

Il faut minimiser la quantit´e de m´ecanisme commun `a plus d’un programme ou utilisateur (typiquement les services de l’OS, comme le service d’acc`es au r´eseau). Les bugs dans ces m´ecanismes empˆechent tous les programmes qui en d´ependent de fonctionner correctement, affectant ainsi une grande partie du syst`eme ; ou peuvent involontairement servir d’int´erm´ediaire pour des communications non-autoris´ees (canal cach´e). Minimiser ces m´ecanismes r´eduit les possibilit´es de bugs, donc de failles, dans ces m´ecanismes. Finalement, un m´ecanisme non minimal impose des contraintes suppl´ementaires aux programmes qui l’utilisent : il vaut mieux mettre du code dans des librairies facilement rempla¸cables, que dans des m´ecanismes communs fix´es.

Un programme utilise g´en´eralement un m´ecanisme commun parce que cela lui est n´ecessaire pour accomplir une action ; et ce m´ecanisme commun est g´en´eralement le seul moyen pour ce faire. Le m´ecanisme est donc de confiance. On peut ´etendre le principe de minimisation des m´ecanismes communs en la « minimisation des m´ecanismes de confiances » (appel´e r´eduction ce de qui doit ˆetre digne de confiance par Neumann [Neu04], ou minimisation du code de confiance par Bernstein [Ber07]).

Il y a plusieurs r´ealisations modernes de ce principe. Par exemple, les exonoyaux [EKJO95], en supprimant du noyau le code qui impl´emente les « abstractions », minimisent les m´ecanismes communs. Les VMMs (e.g. [BDF+

03]) font de mˆeme. Les micronoyaux r´ealisent une autre forme de minimisation des m´ecanismes communs. En permettant aux programmes de choisir de quels services ils ont besoin, ils permettent de r´ealiser une minimisation du TCB (i.e. ensemble des tˆaches de TCB

confiances) par tˆache [HPHS04]. La notion de TCB est en effet relative : un service peut ˆetre de confiance pour une tˆache et ne pas l’ˆetre pour une autre, suivant que ces services sont n´ecessaires ou non au bon fonctionnement de la tˆache.

2.2.2.7 Autres principes

Il existe d’autres principes de s´ecurit´e qui concernent plutˆot des contraintes de g´enie logiciel, et sont moins importantes dans le cadre de cette th`ese. Nous les mentionnons bri`evement.

Conception ouverte Il ne faut pas que le fait que la conception soit tenue secr`ete soit consid´er´e comme un m´ecanisme de s´ecurit´e. Ouvrir la conception permet de ne pas se reposer sur ce fait.

La publication des m´ecanismes de s´ecurit´e d’Anaxagoros dans le pr´esent rapport de th`ese t´emoigne du fait que notre conception est ouverte. De plus lorsqu’un

programme n’est pas consid´er´e comme de confiance, nous le consid´erons comme malicieux et omniscient (cette hypoth`ese est appel´ee « presumed collusion » par Shapiro [Sha99, p. 60]).

S´ecurit´e pr´evue au d´epart On ne peut pas modifier un syst`eme existant pour le rendre s´ecuris´e [Gas88]. La s´ecurit´e doit ˆetre prise en compte lors de toutes les ´etapes du cycle de d´eveloppement, de la conception `a l’impl´ementation.

Acceptation psychologique L’interface doit ˆetre con¸cue pour ˆetre facile `a utiliser, pour que les utilisateurs se servent des m´ecanismes de protection cor- rectement. Elle doit par exemple correspondre `a l’image que se font les utilisateurs des m´ecanismes de protection. Nous n’avons pas vraiment d’utilisateurs dans notre syst`eme, mais nous consid´erons les d´eveloppeurs d’applications comme les utilisateurs du syst`eme. Cela signifie simplement que les concepts de s´ecurit´e doivent ˆetre simple `a appr´ehender. Par exemple, la structuration objet est maintenant relativement bien connue des programmeurs ; les syst`emes `a capacit´es structur´es de mani`ere orient´ee objet [Lev84] sont donc a priori simple d’utilisation pour ces programmeurs.