Réactions
  1. bluestorm, Emily, et les chameaux
  2. L'innocence est un mythe : les programmes fonctionnels nécessairement impurs
  3. Histoire de minorité et d'informatique
  4. Détection automatique de bugs
  5. Cohérence des effets de bord
  6. Sécurité et interface utilisateur
  7. Génération de tests, compilateurs, et preuve formelle

bluestorm, Emily, et les chameaux

(Gabriel Scherer (gasche) @ 2009-08-07 15:14:24)

Il était une fois un gars sans blog, mais qui voulait publier des choses. Un autre, qui avait un blog (quoique primitif, sans commentaires, sans JavaScript et sans Flash, OMG), vint, et lui proposa astucieusement d’héberger son contenu. Shazam !

Voici donc le premier billet de bluestorm, qui relate ses aventures dans le monde merveilleux des bêbêtes sous haute sécurité (et des concepts liés, bien évidemment), avec l’exemple d’Emily, une belle chamelle s’il en est (et rien à voir avec le modèle de mes dessins). —rz0

C’est ma première réaction. Wouhou ! Je suis débutant, merci d’être indulgent. Comment choisir le paper auquel réagir le premier ? J’ai commencé par rédiger une liste des papers que j’avais envie de traiter, en me promenant au hasard dans mon répertoire ~/Papers, et maintenant je prends arbitrairement le premier de la liste pour me forcer à commencer.

Le paper est How Emily Tamed the Caml (PDF, 16 pages). Il concerne la sécurité informatique, domaine que je connais très mal, et plus précisément une approche qui me fascine : le principe du moindre privilège (POLA, Principle Of Least Authorithy), et la capability-based security.

En deux mots (je vais développer un peu plus ensuite), la question que pose l’article est la suivante : comment faut-il modifier un langage de programmation généraliste pour lui faire respecter les principes du POLA ? On prend un langage de programmation généraliste (ici OCaml), et on le domestique (tame) en lui retirant toutes les fonctionnalités qui cassent le POLA ; un programme écrit dans le langage domestiqué donne donc des garanties de sûreté nettement plus fortes.

Je connais très mal le domaine de la sécurité informatique, donc il faut prendre tout ce que je dis avec prudence. Il y a certainement des imprécisions ou des erreurs dans ce que je vais dire. Si cela vous a intéressé, n’hésitez surtout pas à laisser un commentaire (constructif si possible), mail (note d’édition : bluestorm@, chez GMail, gmail.com, pour ceux qui ne sauraient vraiment pas) ou autres.

POLA, capability-based security

Si vous connaissez déjà tout ça, pas la peine de lire mon introduction, sautez directement aux deux derniers paragraphes de cette réaction, qui résument le contenu du papier.

Privilèges, POLA

On appelle privilège la possibilité de faire quelque chose sur l’ordinateur. Un utilisateur dispose par exemple du droit de renommer ses fichiers, ou d’en ajouter de nouveaux dans son répertoire personnel. Il n’a pas forcément tous les droits, par exemple s’il n’est pas administrateur de la machine il n’a pas forcément le droit d’installer des logiciels ou changer la configuration du système.

Dans la plupart des systèmes actuels, un programme est affilié à un utilisateur (la personne qui l’a lancé) et hérite exactement des droits de l’utilisateur : il a le droit de modifier les fichiers du répertoire personnel, mais pas de modifier la configuration du système. S’il avait plus de droits que l’utilisateur, ce serait une faille de sécurité : il pourrait par exemple modifier la configuration du système pour se lancer au démarrage et se répliquer sur le réseau (c’est comme ça que fonctionnent les virus).

Quand on y pense, il n’est pas forcément normal que chaque programme lancé par l’utilisateur ait accès à tous les privilèges de l’utilisateur. Par exemple si je lance un programme pour me donner l’heure qu’il est, il n’a pas besoin du droit de supprimer des fichiers dans mon répertoire, et s’il essaie de le faire c’est sans doute une erreur de programmation, ou carrément un programme malicieux fournit par un méchant programmeur qui essaie de me faire croire qu’il affiche l’heure pour effacer mes données personnelles. Dans les systèmes d’exploitations modernes, il est donc possible de restreindre les droits de certains programmes.

Le POLA est un principe qui résume cette approche : chacun doit avoir à sa disposition exactement l’ensemble de privilèges dont il a absolument besoin pour faire son travail, et rien de plus.

Lien

Granularité

C’est un principe enfantin qui n’est pas appliqué complètement par les systèmes d’exploitations actuels. En particulier les systèmes dérivés de UNIX utilisent des dérivés de l’approche ugo, où l’on attribue les droits selon un découpage utilisateur/groupe (certains utilisateurs ou groupes d’utilisateurs ont des droits spécifiques sur certains fichiers/programmes/outils), qui est une distinction beaucoup moins fine. Il y a eu des améliorations depuis les premiers temps d’UNIX, mais à ma connaissance aucun système grand public ne respecte vraiment les principes du POLA à un niveau suffisamment fin.

Parce que l’on peut appliquer le POLA à un grand nombre de niveau. Au niveau des utilisateurs, c’est grosso-modo ce que font les administrateurs systèmes consciencieux aujourd’hui. Au niveau des programmes, c’est déjà nettement plus délicat. On pourrait même appliquer le POLA à l’intérieur des programmes en assignant des droits différents aux différents modules et composants logiciels du programme (la couche GUI aurait des droits d’affichage, et pas le reste, par exemple). C’est ce que permettent les langages capability-based.

Il y a donc une idée de granularité : dans l’absolu tout le monde est d’accord sur le fait que le POLA est la meilleure approche de la sécurité, mais jusqu’à quel niveau de détail on peut l’appliquer ?

Capabilities

Les capabilitiesα sont une autre idée qui est fortement reliée au POLA. Elles ne sont pas nécessaires pour construire un système qui respecte le POLA, mais leur élégance fait que les gens qui travaillent dans ce domaine les utilisent très souvent.

Dans les systèmes d’exploitation et les langages actuels, on fait une distinction très nette entre une action, et l’autorisation de faire cette action. Par exemple, n’importe quel programme peut exécuter la fonction qui lit le contenu d’un fichier, il suffit de donner l’adresse du fichier sur le disque. Cependant, cette fonction va parfois échouer si le programme n’a pas les droits nécessaires pour lire ce fichier, et renvoyer une erreur. Le « moyen d’accès » au fichier est son adresse, et il y a une phase de sécurité séparée.

L’idée des capabilities est que le moyen d’accès et le droit d’accès peuvent être réunis en une seule et même entité. Une capability est un objetβ qui contient à la fois la méthode pour faire une action et les droits pour l’effectuer. Si le système donne à un programme la capability « lire le fichier machin », le programme peut l’utiliser pour lire le fichier, ou bien la donner à un autre programme qui aura à son tour le pouvoir de lire le fichier. S’il n’a pas reçu cette capability, le programme n’a pas le droit de le lire, mais il n’a même pas le moyen concret d’essayer de le lire.

α : Je n’ai pas trouvé de traduction en français qui me plaise, je ne sais pas si "capacité" convient.

β : Je parle ici d’objet au sens large et ça n’a aucun rapport avec la Programmation Orientée Objet.

Lien

Rôle des langages de programmation

Support par le système

On a déjà écrit des systèmes d’exploitation miniatures basés sur le concept de capabilities ; par exemple dans le projet EROS/CaprOS. C’est un noyau de système d’exploitation.

Le problème c’est que l’approche par capabilities est radicalement différente des méthodes des systèmes actuels, et il est très difficile d’assurer la compatibilité entre un système d’exploitation capability-based et un logiciel développé pour un système grand public : lui s’attend à ce qu’on lui donne des droits sur tout et n’importe quoi, et si on le fait on perd les bénéfices en matière de sécurité ; il faudrait donc ré-écrire en profondeur le logiciel pour qu’il respecte le POLA. Concrètement, ces projets de recherche ne sont donc utilisés par essentiellement personne parce qu’ils ne sont compatible avec aucun des logiciels existants, et l’effort pour les rendre utilisables serait énorme, bien supérieur au budget des équipes de recherche concernées.

Support par le langage de programmation

Il est cependant possible de mettre en place le POLA localement, au sein d’un programme. Il suffit essentiellement de restreindre l’interface entre le programme et le système d’exploitation (qui est laxiste et donne trop de droits) à une petite couche "administratrice" (qui détient tous les droits du programme), qui se charge de répartir ces droits aux autres composants du programme sans leur en donner trop.

Cela limite un peu le cadre de la chose puisque c’est le programmeur qui s’occupe de sécuriser son propre programme. On ne peut pas faire confiance par exemple à un méchant pour écrire ses programmes de cette manière, il ne va pas se tirer une balle dans le pied ! Cela peut toujours être utile dans le cas où on propose au méchant de coder quelque chose pour notre propre programme : si son code est inclus dans une partie sécurisée, et que la sécurité est vérifiée par le compilateur, il ne peut pas faire de bêtises. C’est aussi utile pour les erreurs qui ne sont pas volontaires mais accidentelles : si on a un bug dans une partie du programme, ça peut mal se passer, mais il ne fera rien qui lui est interdit. S’il y a par exemple une vulnérabilité dans une partie du code qui permet à des attaquants de faire des actions non prévues, ils seront limités par le peu de droits dont dispose cette partie du code, donc c’est très intéressant.

Pour avoir un tel support au sein du programme, il faut des langages de programmation pensés pour. Le langage le plus connu dans ce domaine est E.

Il faut d’une part que le compilateur du langage puisse vérifier que la sécurité est bien respectée (qu’une partie du code qui n’est pas censée lire le contenu de fichiers ne puissse pas quand même demander au système d’exploitation de le faire), et d’autre part que les fonctionnalités du langage ne permettent pas d’écrire du code qui casse cette protection. Par exemple, si une partie du programme peut écrire en mémoire la clé d’accès au contenu du fichier, une partie qui n’est pas censée lire de fichier mais peu lire dans la mémoire peut utiliser cette clé et outrepasser ses droits, sans que le compilateur puisse s’en rendre compte et signaler l’excès de privilège.

Lien

Cas d’Emily

Ce que présente le papier cité c’est la transformation d’un langage généraliste, qui n’a pas été pensé à la base pour respecter le POLA, en un langage sécurisé. Il s’agit essentiellement de retirer toutes les fonctions « dangereuses » de la bibliothèque standard, en les remplaçant par des équivalents « sécurisés » qui rendent explicite les capabilities nécessaires. Par exemple la fonction open_out de Caml, qui permet d’ouvrir un canal en écriture vers n’importe quel fichier, est retirée et n’est plus accessible à l’ensemble du programme. Seule la petite couche d’interface avec le système peut créer des canaux à volonté, et les autres parties du programme doivent lui demander pour recevoir un canal, ou plutôt la capability correspondante, qui encapsule dans un record le canal et les fonctions d’entrée/sortie qui y sont liées.

Le papier décrit donc d’une part les modifications apportées à la bibliothèque standard OCaml, d’autre part la découpe entre la partie « toute puissante » du programme qui a tous les droits donnés par le système, et les parties sécurisées : la partie « toute puissante » doit être la plus petite et la plus simple possible pour ne pas comporter d’erreurs/failles. Il présente des exemples de programmes sécurisés, programmes en ligne de commande ou programmes avec GUI. Il discute aussi les impacts de cette transformation sur le style de programmation, ou les performances des programmes écrits de cette manière.

Pour résumer, je trouve que cet article est une bonne introduction aux problématiques de sécurité d’un langage de programmation. Il est très accessible, n’approfondit pas énormément et ennuirait sans doute un connaisseur du sujet, mais pour un inculte comme moi ça a constitué une lecture agréable.

Lien