Capsicum, une séparation fine des privilèges pour UNIX

Posté par  . Modéré par tuiu pol. Licence CC By‑SA.
94
21
mar.
2011
Sécurité

Le projet Capsicum, lancé l'année dernière, tente d’adapter le modèle de sécurité par capacités (« capabilities ») aux systèmes UNIX. En deux mots, il s’agit de permettre aux applications de faire tourner certaines parties de leur code dans des « sandboxes » (bacs à sable) aux droits très restreints, gérés finement, avec la possibilité de recevoir ou de déléguer dynamiquement une partie de ces droits.

C’est une approche de la sécurité qui mise sur la flexibilité et l’intégration directe dans les applications (au contraire de politiques externes décidées par l’administrateur système, comme avec SELinux) pour respecter le Principle of Least Authority, qui recommande qu’un bout de programme donné fonctionne avec seulement les droits dont il a besoin pour accomplir sa tâche. Ainsi, les conséquences d’une faille sont réduites et les vecteurs d’attaque diminuent énormément. Par exemple, je ne veux pas que le logiciel qui lit mes fichiers PDF ait le droit de lire le contenu de mon répertoire personnel et d’envoyer des e-mails.

Capsicum introduit de nouveaux appels et objets système, qui demandent une (relativement petite) modification du noyau, ainsi qu’une bibliothèque logicielle en espace utilisateur pour utiliser ces nouveaux appels système. FreeBSD a déjà fait les modifications nécessaires, et les chercheurs ont pu facilement convertir plusieurs applications au modèle Capsicum : tcpdump, dhclient, gzip et, avec l’aide d’un développeur Google, le navigateur Web chromium.

Capsicum peut ainsi renforcer considérablement la sécurité des applications UNIX classiques, sans demander de les recoder entièrement. Reste à voir si les développeurs du monde du Libre seront convaincus par ces approches compartimentées, et prêts à les prendre en compte lors de la conception de leurs logiciels.

Sommaire

La sécurité par capacités

La sécurité par capacités n’est pas une idée nouvelle : elle a été introduite en 1966 par Dennis et Van Horn, dans un article concernant les systèmes multi-utilisateur. Une capacité est une référence non-forgeable qui, simultanément, désigne un objet du système (fichier, périphérique…) et décrit une action autorisée sur cet objet (renommer le fichier, écrire sur le périphérique, etc.). La seule façon d’effectuer une action est de posséder et d’activer une capacité associée.

Dans un système UNIX classique (UNIX n’existait pas en 66, c’était la naissance de son ancêtre MULTICS), ce sont les objets du système qui « connaissent » les droits qui les concernent. Par exemple, les permissions d’un fichier indiquent quels utilisateurs peuvent y accéder et de quelle façon. Les capacités renversent la perspective : ce sont les agents du systèmes qui ont à leur disposition une liste d’actions autorisées.

Cela permet une gestion plus dynamique et plus fine des droits, car la notion d’« agent » peut être très fine : quand un programme lance un sous-programme, ou quand un utilisateur lance un programme, il peut choisir naturellement quelles capacités lui transmettre. Le Principle Of Least Authority est beaucoup mieux respecté que dans un système UNIX classique, où tous les processus lancés par le même utilisateur ont tous les droits de l’utilisateur : il y a une autorité « ambiante » qui peut être abusée.

Une capacité doit être non-forgeable pour qu’un agent ne puisse effectuer que les actions dont les droits lui ont été attribués. Ainsi, les utilisateurs n’ont pas accès au système de fichiers dans son ensemble, ils ne « voient » que les fichiers sur lesquels ils ont une capacité de lecture. Enfin, le fait de coupler la désignation d’un objet et l’autorité sur l’action qui l’accompagne, permet d'éviter les attaques de type « confused deputy ».

Enfin, attention à ne pas confondre, les capacités du monde de la sécurité sont différentes des « POSIX capabilities », des systèmes de contrôle de droits beaucoup plus grossiers (cf. cet argumentaire).

Aller plus loin :

Une bonne idée longtemps oubliée

Malgré des débuts prometteurs, l’idée des capacités a quasiment été oubliée dans les années 1980. Plusieurs causes ont contribué à cet échec : d’abord, le concept de « renversement de point de vue » par rapport aux Access Control List a paradoxalement répandu l’idée que les capacités n’apportaient en fait rien de nouveau, et que tout ce qui était fait pourrait aussi bien être fait, de façon symétrique, avec les listes d’accès de contrôle. Cette « méconception » ignore le fait que la gestion des droits au niveau de l’agent, et non de l’objet, permet une granularité beaucoup plus fine que les utilisateurs ou groupes utilisés dans les systèmes ACL classiques. Un modèle de droits doit être considéré de façon dynamique (modification et transmission des droits) et pas seulement statiquement, à un instant donné.

De plus, les premiers systèmes de capacités ne permettaient pas la révocation (le fait de retirer des droits qu'on a donné à un autre agent), et permettaient à chaque processus de diffuser ses propres droits sans restriction, ce qui met en péril les modèles de sécurité militaires où l’on veut garantir, par exemple, qu’une personne ayant accès à des documents « top secret » ne peut pas pour autant les faire lire à un simple moussaillon. On a depuis montré que les capacités permettaient en fait ces deux choses, mais le préjugé est resté.

Enfin et surtout, l’énorme succès d’UNIX, ayant une approche fondamentalement opposée à celle des capacités, a rapidement étouffé la recherche de systèmes alternatifs et incompatibles (cf. le pessimiste et grinçant Systems Software Research is Irrelevant (PDF, 23 transparents) de Rob Pike).

Cependant, un petit groupe d’irréductibles a continué à travailler sur les capacités. En particulier, les micro-noyaux (un autre franc succès du monde de l’informatique) ont souvent utilisé des capacités, car leur emploi est très naturel dans un contexte de passage de messages. En particulier les systèmes KeyKOS puis EROS ont montré qu’une conception entièrement basée sur les capacités était possible, sans perte de performances.

Mais les capacités peuvent être déployées à plus haut niveau que le noyau d’un système. Ainsi, Mark Miller a développé le langage de programmation E, épousant entièrement le concept de capacité, qui permet d’écrire des programmes distribués et sécurisés.

Enfin, l’environnement de bureau Capdesk a été écrit en E, et démontre qu’une interface utilisateur peut intrinsèquement favoriser la sécurité. Un exemple simple : sur un système classique, quand un utilisateur veut ouvrir un nouveau fichier dans son application préférée, celle-ci ouvre un « dialogue de choix de fichier » qui lui permet de naviguer dans son système et de choisir le fichier désiré que l’application ouvre ensuite. Mais pour faire cela, l’application doit nécessairement avoir le droit de lecture sur toute l’arborescence de l’utilisateur, pour lui permettre d’y naviguer. Dans CapDesk, le widget « choix de fichier » est en fait un programme externe auquel l’application fait appel, qui a le droit de naviguer dans les répertoires, et qui renvoie finalement à l’application un simple descripteur de fichier avec les bons droits. Ainsi, l’application n’a pas besoin des droits sur le système de fichiers. Enfin, au lieu d’un simple choix « ouvrir / annuler », on peut afficher, selon les besoins de l’application, « ouvrir en lecture » ou « ouvrir en écriture », pour que l’utilisateur soit mieux conscient des droits qu’il choisit de déléguer à l’application.

Mais les innovations révolutionnaires qui demandent de changer complètement de système d’exploitation, de langage de programmation ou d’environnement de bureau n’ont pas percé (de même que le micro-noyau L4, [Lisp] ou [GNUStep]). Les amateurs de capacités ont alors cherché à « amadouer » (tame) des environnements existants, en les restreignant de façon à pouvoir y garantir les bonnes propriétés des systèmes par capacité. Par exemple, il faut retirer d’un langage de programmation les fonctions qui « ajoutent de l’autorité ambiante », comme les fonctions convertissant un chemin en descripteur de fichier (contient l’autorité entière sur le système de fichiers), ou empêcher les conversions de types trop barbares, qui pourraient permettre de forger une capacité. Entre autres, des versions restreintes des langages Java (Joe-E), Scheme, OCaml ont été proposées. Moins le langage met en avant les variables globales et les effets de bord qui risquent de créer des
canaux cachés, plus il est facile à rendre « capability safe ».

Récemment, les capacités ont vu un net regain de popularité dans le cadre de la sécurisation du langage de programmation JavaScript. On a encore du mal à y croire, mais ce « langage bricolé » est devenu le standard de fait pour distribuer du code sur internet. Un environnement fortement multi-utilisateur avec distribution et exécution de code dans tous les sens, c’est un mélange explosif pour la sécurité, et de nombreuses failles ont commencé à apparaître ([XSS]…). Les efforts déployés pour restreindre les sites malicieux (comme le projet FBJS de Facebook) sont mis à mal par les défauts du langage, comme sa gestion abracadabrante des environnements de noms (« scopes »). En utilisant un modèle de capacités, on peut protéger le navigateur et les sites en les aidant à restreindre les droits des scripts exécutés. C’est le thème, entre autres, du prometteur projet Caja de Google. Les acteurs du Web ont même souhaité prendre en compte ces questions dans les nouvelles versions de JavaScript, et ont invité Mark Miller dans le comité de standardisation, pour proposer des évolutions du langage facilitant l’approche par capacités.

Pour approfondir :

  • Capability Myths Demolished (PDF, 15 pages) de Mark Miller, Ka-Ping Yee et Jonathan Shapiro, 2003. Cet article explique les « méconceptions » classiques qui ont fait du tort aux modèles par capacités, comment les corriger. C’est aussi une très bonne présentation des avantages des capacités ;
  • le site du langage E, une mine d’informations (en anglais) sur les concepts sous-jacents, la programmation distribuée et les capacités ;
  • le projet Waterken, un framework Web basé sur Joe-E, qui a raffiné les concepts de capacités dans le contexte de la programmation Web ;
  • l’article User Interaction for Secure Systems (PDF, 16 pages), de Ka-Ping Yee, 2002, montre que négliger l’interface utilisateur, même dans un système respectant le Principle Of Least Authority, peut donner lieu à des problèmes de sécurité ;
  • l’interview sur InfoQ de Mark Miller, où il discute de son travail dans le comité de standardisation de ECMAscript 5 pour obtenir un langage plus propice à la sécurité : ECMAScript 5, Caja and Retrofitting Security. Il y a une vidéo, mais ne fuyez pas tout de suite, un bonne transcription texte est disponible en dessous. Cliquez sur les petits « + » ou « Full page transcript », en bas, pour voir le texte, et sur les titres pour synchroniser à cet endroit de la vidéo ;
  • L’article Object Capabilities and Isolation of Untrusted Web Applications (PDF, 16 pages) de Sergio Maffeis, John Mitchell, Ankur Taly, qui donne une preuve formelle de la sécurité d’un sous-ensemble de JavaScript (travail qui a permis de trouver des failles dans FBJS), et une autre preuve que le sous-ensemble utilisé par Caja est « capability-safe ».

P.S. : John Mitchell a récemment donné un exposé (en anglais) à ce sujet au Collège de France, dans le cadre du cours sur la sécurité informatique qui y a lieu en ce moment. Des transparents sont disponibles, et un enregistrement audio devrait l’être bientôt.

C’est aussi une remarque en passant pour dire que, si vous êtes dans la région parisienne et que vous voulez voir la sécurité vulgarisée pour votre grand-mère, ou presque, par des pointures du domaine, n’hésitez pas à passer au Collège de France le mercredi matin (mais attention, la salle est déjà bien remplie).

Le projet Capsicum

Le monde du développement Web, bien qu’il croule déjà sous le poids de la rétro‑compatibilité et des standards à rallonge, est encore relativement jeune et peut se permettre des expérimentations de fond.

Du côté des systèmes d’exploitation, l’évolution est moins rapide. Les systèmes d’exploitation actuels n’ont pas beaucoup évolué dans le domaine la sécurité, par rapport aux systèmes UNIX initiaux. Des systèmes plus fins ont été proposés, comme SELinux : l’idée d’ensemble est que ce sont les administrateurs1 qui décident des politiques de sécurité en écrivant des scripts de « profils » regroupant un petit ensemble de droits, et qui forcent les applications à rentrer dans ces cadres. Malheureusement, ces politiques restent difficiles à écrire, maintenir et déployer, et ces approches n’ont donc pas encore sensiblement amélioré la situation pour les systèmes grand public.

L’approche la plus utilisée est celle des « sandboxes », qui consistent
à compartimenter des applications en utilisant les facilités du
système d’exploitation (« chroot » ou « seccomp », les jails FreeBSD,
etc.), mais leur gestion des droits est beaucoup moins fine que les
systèmes de capacités, avec souvent des approches « tout ou rien »
(par exemple, « seccomp » interdit tout sauf « read », « write » et « exit »).

Le projet Capsicum cherche à « amadouer » les appels système, en trouvant un compromis entre la flexibilité-fouillis des capacités (une capacité = un droit) et l’autorité ambiante écrasante des systèmes UNIX habituels. Ses concepteurs ont choisi de raffiner les descripteurs de fichiers UNIX en leur ajoutant des masques de droits permettant une gestion fine des droits (plus de 60 masques différents) auxquels ils sont associés. L’intérêt de réutiliser les descripteurs de fichiers au lieu d’une abstraction dédiée, est de rester dans un style de programmation qui est familier aux programmeurs système UNIX.

Le noyau maintient pour chaque processus un drapeau (flag) booléen qui indique s’il est en « mode capacités » : un programme classique (non sécurisé par Capsicum) ne l’est pas, mais peut choisir d’y entrer avec le nouvel appel système « cap_enter ». Ce drapeau est hérité par tous les processus créés, et ne peut être retiré. Quand le drapeau est activé, tous les appels système exposant de l’autorité ambiante sont interdits, d’autres sont restreints (par exemple « openat », qui ouvre un fichier à partir d’un répertoire donné, n’accepte plus que les chemins relatifs désignant un fichier dans le sous‑répertoire), et ceux qui restent sont légèrement modifiés pour prendre en compte les masques de droits du descripteur de fichier. Il y a aussi des appels système de bas niveau pour réduire les droits d’un descripteur de fichier, ou lancer un nouveau processus en lui transmettant une partie de ses droits. Enfin, la bibliothèque utilisateur libcapsicum propose des composants de plus haut niveau qui permettent de retrouver le niveau de confort (tout relatif) des programmes systèmes habituels, et les opérations courantes de manipulation de droits.

Les descripteurs de fichiers ne sont pas le seul espace de nom global des systèmes UNIX (malgré les efforts dans ce sens du projet Plan9). Les sockets réseau, timers et toutes les interfaces System V et POSIX bizarres pour manipuler, par exemple, la mémoire partagée, sont aussi contrôlés, ce qui est souvent négligé par les solutions de « sandboxing » existantes.

L’idée est de découper les applications en une partie privilégiée, qui tourne avec tous les droits qu’elle avait au lancement, et une ou plusieurs parties compartimentées, qui sont sous un appel à « cap_enter » avec exactement les droits nécessaires. Le but du jeu est que toutes les parties sensibles (en C, la manipulation de chaînes) soient compartimentées et que la partie privilégiée réalise le moins de choses possibles, ceci afin de réduire la surface d’attaque. Plus le découpage est fin, plus le logiciel respecte le Principle of Least Authority. Et la sécurité en est d’autant renforcée.

(1) : Plus généralement, les approches par Mandatory Access Control (SELinux) et par capacités sont complémentaires : le MAC vise à permettre à un administrateur système de contrôler les droits selon les besoins de son environnement, alors que les capacités servent
au développeur pour contrôler les droits selon les besoins de son application.

En savoir plus :

  • la page du projet Capsicum au laboratoire sécurité de l’université de Cambridge (GB) ;
  • les transparents de la présentation (PDF, 31 pages) donnée à la conférence de sécurité USENIX en août dernier ;
  • l’article « Capsicum: practical capabilities for UNIX » (PDF, 17 pages), par Robert Watson et Jonathan Anderson (Cambridge), Ben Laurie et Kris Kennaway (Google UK). Cet article contient une explication plus détaillée de Capsicum (logique !), mais aussi des rapports d’expériences sur des essais de sécurisation de logiciels existants, et des mesures de performance pour évaluer le surcoût associé à ces modifications. Je les décrirai brièvement dans la prochaine partie, mais si vous voulez des détails, il faut aller lire ce papier. Enfin, l’article contient des comparaisons aux solutions existantes : si vous vous dites « mais, c’est pareil que SELinux / chroot / PLASH ! », il faut aller lire ça.

Et ça marche ?

Les gens de Google qui travaillent sur le navigateur Chromium se sont montrés très intéressés par le projet Capsicum. En effet, Chromium essaie de mettre en place des mécanismes de « sandboxing », ce qui a forcé les développeurs à évaluer les différentes solutions existant sur les principaux OS (Windows, Mac OSX, GNU/Linux, BSD…). Ils ont découvert qu’aucune solution n’est complètement satisfaisante : soit les droits sont trop grossiers, rigides ou difficiles à configurer (Sandbox de MacOS X, SELinux), soit les droits sont très restreints et il faut alors implémenter soi‑même une couche de médiation en utilisant un processus ayant plus d’autorité. Ainsi, la solution de confinement sous Windows et celle utilisant « seccomp » sous GNU/Linux ont demandé des dizaines de milliers de lignes de code supplémentaires, sans pour autant obtenir exactement les droits désirés… Capsicum leur a permis, en modifiant seulement une centaine de lignes de code, de mettre en place une sandbox flexible et répondant à leurs besoins.

Les développeurs de FreeBSD se sont aussi montrés intéressés par la technologie Capsicum, et se préparent à l’inclure dans la prochaine version de FreeBSD. Évidemment, comme Capsicum demande des modifications des appels système du noyau sur des points plutôt sensibles, il faut réussir à convaincre les développeurs de chaque noyau qu’inclure ces modifications vaut le coup… La communauté NetBSD a eu l’air plutôt favorablement intéressée, et un portage pour Linux serait en développement, mais l’inclusion en amont dans ces systèmes n’est pas encore d’actualité.

Du côté des autres applications, les développeurs de Capsicum ont converti les programmes « tcpdump », « dhclient » (tous deux déjà responsables de vulnérabilités liées au traitement des chaînes de caractères, et déjà partiellement compartimentés en utilisant d’autres technologies moins fines) et « gzip ».

Ci‑dessous, les 8 lignes de sécurisation du code de tcpdump. On commence par restreindre l’autorité ambiante des descripteurs de fichiers standard : on ne pourra plus utiliser que « fstat() » sur « stdin ». La fonction « lc_limitfd() » provient de capsicum-core, bibliothèque en espace utilisateur. Ensuite on passe en mode capacités avec « cap_enter ». À partir de ce moment, les paquets reçus seront analysés (opération sensible) dans un environnement à autorité minimale.

if (lc_limitfd(STDIN_FILENO, CAP_FSTAT) < 0)
    error("lc_limitfd: unable to limit STDIN_FILENO");
if (lc_limitfd(STDOUT_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0)
    error("lc_limitfd: unable to limit STDIN_FILENO");
if (lc_limitfd(STDERR_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0)
    error("lc_limitfd: unable to limit STDERR_FILENO");
if (cap_enter() < 0)
    error("cap_enter: %s", pcap_strerror(errno));

Les leçons tirées de ces expériences sont multiples. D’une part, les développeurs ont pu observer que sur une application réelle, le surcoût en performance lié au « sandboxing » est « assez » faible (moins de 10 % dans les cas défavorables, et un petit surcoût constant en général). Il y a quand même un coût qu'ils essaient de réduire en optimisant leur implémentation. Paradoxalement, Capsicum est moins coûteux que d’autres solutions de « sandboxing », donc, en convertissant un logiciel déjà compartimenté vers Capsicum, on peut en améliorer légèrement les performances, en plus d’obtenir une gestion plus fine des droits.

D’autre part, ils ont constaté que les applications qui reposaient déjà sur un modèle compartimenté avec « sandboxing » étaient extrêmement faciles à convertir vers Capsicum. Mais, le cas d’applications grand public n’ayant aucune expérience de séparation des privilèges risque d’être plus délicat…

La grande force de Capsicum par rapport aux autres solutions utilisant les capacités, c’est qu’il s’agit d’un raffinement, et non d’un remplacement, des systèmes de droits UNIX usuels : on peut convertir les applications une par une, et même module par module. Une mise en œuvre progressive, concentrée sur les applications sensibles, est donc possible. Mais il faut quand même motiver les développeurs à prendre ces problématiques en compte.

À quand Capsicum disponible sur Linux, et LibreOffice, Firefox et KDE respectant le principe de moindre autorité ? Qui s'y colle ?

Plus de détails croustillants :

  • la discussion sur la liste FreeBSD en vue d’une intégration dans la 9.x. Ce message, en particulier, contient des comparaisons à d’autres solutions de sécurité ;
  • Capsicum est mentionné dans le rapport d’activité FreeBSD, avec un plan plus détaillé d’intégration dans FreeBSD ;
  • le fil de discussion des gens de NetBSD au sujet de Capsicum ;
  • deux messages (en juin et en janvier) de Heradon Douglas, un ingénieur Google qui travaille à un portage Linux sur ses 20 % de temps libre. On est encore loin d’une intégration en amont…

Aller plus loin

  • # Bravo

    Posté par  . Évalué à 10.

    Bravo pour cette dépêche très instructive.

    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: Bravo

      Posté par  . Évalué à 5.

      Tout à fait !
      Je ne suis pas certain d'avoir tout compris, mais la dépêche est vraiment bien rédigée.
      Merci !

  • # Trop complexe

    Posté par  (site web personnel) . Évalué à -9.

    Une bonne idée longtemps oubliée

    Mais les innovations révolutionnaires qui demandent de changer complètement de système d’exploitation, de langage de programmation ou d’environnement de bureau n’ont pas percé (de même que le micro-noyau L4, Lisp ou GNUStep).

    Ça se comprend : trop compliqué.

    Le projet Capsicum

    […] trouvant un compromis entre la flexibilité-fouillis des capacités (une capacité = un droit) et l’autorité ambiante écrasante des systèmes UNIX habituels.

    […] des masques de droits permettant une gestion fine des droits (plus de 60 masques différents)

    Échec.

    Et ça marche ?

    À quand Capsicum disponible sur Linux, et LibreOffice, Firefox et KDE respectant le principe de moindre autorité ? Qui s'y colle ?

    Pas moi. Ni personne d'autre probablement : trop complexe.

    • [^] # Re: Trop complexe

      Posté par  . Évalué à 10.

      Je suis d'accord avec toi sur le fait que le compromis, où une passe de "une capacité = une action" à 60 masques a augmenté la complexité. Mais en même temps, c'est assez naturel : il s'agit de coller à la programmation système UNIX et ce n'est pas de la nouvelle complexité qui est ajoutée, c'est la complexité existante avec laquelle on s'interface.

      Tu as l'air de trouver que 60 masques c'est trop, mais sur cette page je vois 131 codes de retour d'erreur sur une distribution GNU/Linux classiques. Donc c'est bien l'ordre de grandeur de la complexité gérée aujourd'hui par les programmeurs systèmes.

      Enfin, je t'invite à regarder la liste des capabilités présente dans la manpage de cap_new, sur la page du projet Capsicum. Elle colle essentiellement exactement au nom des appels systèmes tolérés par le système : tu veux appeler getsockname ? Il faut que le masque CAP_GETSOCKNAME soit mis. La plupart des masques de capacité ont ainsi une lecture directe, et c'est donc une forme de complexité où "tu paies à l'usage" : soit tu connais l'appel système correspondant et tu l'utilises dans ton programme, et alors oui tu dois te soucier de ce masque, soit tu n'en as jamais entendu parler et tu n'as pas besoin de t'en servir. Je ne pense pas que la complexité ajoutée soit donc si énorme.

      De toute façon les responsables du projet Capsicum ne prétendent pas avoir inventé la recette miracle. Ce sont les premiers à reconnaître (dans un des messages de la mailing-list que j'ai mis en lien) qu'il reste des améliorations à faire sur la "programmabilité", le fait de rendre agréable à utiliser pour les programmeurs cette finesse de gestion des droits. Mais je pense (et clairement eux aussi) que ça reste une avancée intéressante dans le domaine, qui a des avantages que les solutions existantes n'ont pas su réunir.

      Personne ne prétend que faire du logiciel parfaitement sûr est exactement aussi facile que faire du logiciel sans se soucier de la sécurité. Dans un système à autorité ambiante on n'a pas besoin de se préoccuper des droits, ils sont là quand on en a besoin. Dans un système qui essaie de respecter le Principle Of Last Privilege, cette gestion des droits est rendue explicite. Une personne qui ignorait totalement les problématiques avant va donc trouver qu'il doit s'occuper de plus de choses. Par contre, une personne qui avait déjà mené une réflexion sur la compartementalisation¹ pourra au contraire s'appuyer sur des outils pour la rendre plus concrète et en vérifier directement l'efficacité.

      ¹: je rappelle que la compartementalisation des logiciels ne sert pas que pour la sécurité, mais aussi pour la modularité, la maintenabilité, la fiabilité, etc. Par exemple, les gens qui mettent en avant les architectures avec micro-noyaux ne s'intéressent pas en premier à la sécurité en général. De même la raison de séparer les pages dans Chrome vient plus de considérations de fiabilité. Faire ce raisonnement plus fin, que ce soit au départ pour des raisons de sécurité ou pas, a donc des avantages dans de nombreux domaines.

      Même une fois qu'on utilise des capacités, la finesse de la gestion des droits peut être décidée progressivement. En fait en général on ne respecte jamais absolument le Principle of Least Authority : on approxime (supérieurement, sinon ça ne marche pas) les droits nécessaires. On peut commencer par faire une approximation grossière, ce qui donne des bénéfices de sécurité moins importants, mais demande moins d'effort pour le programmeur. Selon le degré de criticité du logiciel ou de motivation des programmeurs, on peut ensuite affiner en considérant plus précisément le comportement et le besoin en autorité des différentes parties du programme et de ses sous-programmes. Ce n'est pas un choix binaire, tu es libre de décider la quantité d'effort que tu investis selon tes priorités. Mais ça ne veut pas dire qu'il faut rien faire; justement, avec peu d'efforts on peut obtenir un bénéfice important (passer de "rien" à "un truc grossier mais raisonnable").

    • [^] # Re: Trop complexe

      Posté par  . Évalué à 2.

      C'est claire que ça ne perceras jamais face à SELinux qui lui est vraiment simple à mettre en place ؟

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Trop complexe

      Posté par  . Évalué à 7.

      Tu prétends que Capsicum est trop compliqué à utiliser et que personne ne l'utiliserait sur Linux, mais pourtant je pense que les développeurs de Chrome eux seraient très intéressés si Capsicum devenait un 'standard Linux': cela leur simplifierait la vie!

      Pour KDE et Gnome, certains portions comme le 'thumbnailer' devraient être sandboxé: autrement la moindre faille de sécurité dans n'importe quel décodeur de format obscur devient très génant..

  • # Wow

    Posté par  (site web personnel) . Évalué à 5.

    Présenté comme tu l'as fait, ça a l'air génial!

    J'avoue que pour une appli simple comme tcpdump, j'arrive à imaginer la chose, et le code que tu montres semble plutôt clair; maintenant sur un programme comme chromium, qui doit toucher des fichiers un peu partout, utiliser les interfaces réseau, lancer des processus, je pense que ça doit poser tout un tas d'autres soucis.

    J'ai une question: d'où viennent les 10% de pertes de performances?
    Est-ce qu'à chaque appel système la capacité du processus est checkée?

    D'autre-part, si j'ai bien compris, c'est au développeur de se mettre dans ce mode, en spécifiant à un moment donné dans son code les choses que sont processus aura le droit de faire.
    Si jamais un troublion décide de changer tous les appels vers cette librairie utilisateur et de les diriger vers une fonction bidon (en modifiant l'executable), genre printf, on perd tout l'avantage de la solution. (bon il faut aussi effectivement réussir à corrompre un executable à priori, ce qu'un hacker ne pourra pas faire aussi facilement à l'origine si le dit executable est "capsicumé").

    • [^] # Re: Wow

      Posté par  . Évalué à 10.

      J'avoue que pour une appli simple comme tcpdump, j'arrive à imaginer la chose, et le code que tu montres semble plutôt clair; maintenant sur un programme comme chromium, qui doit toucher des fichiers un peu partout, utiliser les interfaces réseau, lancer des processus, je pense que ça doit poser tout un tas d'autres soucis.

      C'est vrai, mais en pratique le besoin de compartementalisation a été pris en compte dès la conception de chromium, et l'intégration de Capsicum s'en est retrouvée d'autant facilitée. L'article de Capsicum détaille un peu plus les modifications apportées à chromium; en substance, ils ont ajouté 100 lignes de lc_limitfd, comme les 6 que j'ai montrées pour tcpdump, et remplacé un morceau de leur impl. Linux par un morceau de leur impl OSX qui se prêtait mieux aux capacités sur ce point précis.

      Leur comparaison aux autres méthodes de sandboxing utilisées pour Chromium est assez positive (bon après, évidemment, ce sont les auteurs de Capsicum, donc ce n'est pas une évaluation indépendante):

      • d'après eux, mettre en place une sandbox sous Windows c'est assez galère, et ils se sont retrouvé à tout interdire ou presque, mais communiquer avec un process non sandboxé chargé d'implémenter lui-même le contrôle d'accès désiré. Plus de 22 000 lignes de code au total

      • un peu le même problème (en moins pire) avec seccomp : plus de 11 000 lignes de code au total

      • pour les deux approches MAC (Seatbelt de Mac OSX et SELinux), ils se plaignent d'un manque de flexibilité, d'une gestion de droits au final moins fine qu'avec Capsicum (par design pour Seatbelt, et par difficulté pour SELinux), et surtout d'un manque de flexibilité dynamique : les politiques d'accès doivent être fixées avant le lancement du programme et ne peuvent pas évoluer dynamiquement, contrairement à la gestion des droits dans un système à capacité.

      J'ai une question: d'où viennent les 10% de pertes de performances? Est-ce qu'à chaque appel système la capacité du processus est checkée?

      Oui, chaque appel système est affecté par le mode capacité. Les coûts sont variés et très détaillé dans l'article, que je t'incite à regarder si tu veux plus de détail : il y a des micro-benchmarks des principaux appels systèmes concernés, et des tests plus réalistes sur les programmes entiers (gzip). Le nombre de 10% que j'ai donné est le surcoût sur l'appel système fstat (il fallait bien choisir quelque chose pour donner un ordre d'idée...).

      Dans le cas de gzip, le coût de capsicum ajoute seulement un surcoût constant, puisque le gros de l'application est de la compression qui se fait sans utilisation de droits particuliers. Avec l'implémentation actuelle ils ont mesuré un surcoût de 2.37 millisecondes, ce qui est non-négligeable (par rapport au temps total de gzip) pour de petites entrées. Pour des entrées de taille 512K, cela représente 5% du temps de calcul (dans leurs tests), et ensuite cela devient vite négligeable.

      Les auteurs précisent qu'ils comptent travailler à optimiser un peu leur code. J'imagine qu'ils ont commencé par obtenir une version fonctionnellement satisfaisante au début, sans mettre l'accent sur les performances, et qu'il y a une marge de progrès à faire. Mais dans tous les cas, ce genre de vérifications supplémentaires aura toujours un coût; c'est au développeur de faire un compromis, selon la nature de son application, ses besoins en sécurité et en performance.

      Si jamais un troublion décide de changer tous les appels vers cette librairie [..] on perd tout l'avantage de la solution.

      Si un attaquant modifie un exécutable qui est lancé avec les droits utilisateurs (que l'exécutable ait prévu au départ d'utiliser capsicum ou pas), effectivement il peut faire ce qu'il veut dans les limites des droits de l'utilisateur. Capsicum ne change quelque chose que pour les processus qui tournent avec le 'capability flag', c'est à dire après l'appel de cap_enter, ou encore les processus fils lancés par des processus sous cap_enter.

      En gros, si tu appelles un programme "foo" modifié par l'attaquant depuis ton shell, il peut faire un peu ce qu'il veut; par contre si un programme "bar" géré par capsicum appelle "foo", il sera restreint aux droits qu'à "bar". C'est justement l'intérêt du Principle of Least Authority: si les droits de "bar" sont minimaux, l'attaquant (ou simplement tout problème lié à un bug non intentionnel) est très limité.

  • # Proto-implémentation

    Posté par  (site web personnel) . Évalué à 2.

    N'y aurait-il pas déjà un embryon d'implémentation de certaines capacités dans Linux ? Pour faire des trucs comme écouter sur un port réseau privilégié ?

  • # Relativisont

    Posté par  . Évalué à 3.

    Petites precisions diverses et variées: - chroot n'est pas considéré comme un élement de sécurité même s'il est souvent utilisé pour ca... - SELinux ne "ralenti" les perfs que de 7% ou moins (mais 10+7 ca fait 17% d'un coup, ca fait beaucoup) - Il est possible d'écrire du code SELinux pour les applications sans recoder grand chose évidement - C'est aussi possible via d'autres mecanismes "MAC" par ex RSBAC (rsbac.org) ou AppArmor (et sans doute d'autres) - RSBAC permet même d'appeler les programmes via rsbac_jail (via le code ou externe) pour réaliser ce type même de sandboxes

    • [^] # Re: Relativisons

      Posté par  . Évalué à 5.

      chroot n'est pas considéré comme un élement de sécurité même s'il est souvent utilisé pour ca...

      Que veut dire cette phrase ? Un outil utilisé pour contribuer à la sécurité d'un système est un "élément de sécurité", qu'il aie été conçu pour cela ou non.
      Chroot entre dans la composition des "Linux containers" ( http://lxc.sourceforge.net/ ) qui peuvent être utilisés pour sécuriser un système. Doit-on reduire chroot et LXC à des softs de sécu ? Sans doutes pas.
      Ces logiciels apportent-ils des fonctionnalités de sécurité ? On aurait du mal à en douter.

      • [^] # Re: Relativisons

        Posté par  . Évalué à 3.

        Que veut dire cette phrase ? Un outil utilisé pour contribuer à la sécurité d'un système est un "élément de sécurité", qu'il aie été conçu pour cela ou non. Chroot entre dans la composition des "Linux containers" ( http://lxc.sourceforge.net/ ) qui peuvent être utilisés pour sécuriser un système. Doit-on reduire chroot et LXC à des softs de sécu ? Sans doutes pas. Ces logiciels apportent-ils des fonctionnalités de sécurité ? On aurait du mal à en douter.

        Sauf qu'un chroot seul, n'apporte aucune sécurité. Il apporte au mieux une illusion de sécurité. Illusion que n'importe quel kiddie sachant taper "chroot exploit" dans google pourra remettre en question.

        Qu'il soit utilisé par LXC où autre ne change pas grand chose. Je suis sûr que LXC utilise printf aussi, c'est par pour autant que c'est un logiciel de sécurité. Et heuresement qu'LXC n'utilise pas que chroot ;)

        • [^] # Re: Relativisons

          Posté par  (site web personnel) . Évalué à 2.

          s/un chroot seul/un chroot par défaut

          N'existe t il pas des méthodes de durcissement du chroot par défaut ? Il me semble que si. Des simples, et des plus complexes et complets, tel CONFIG_GRKERNSEC_CHROOT_*
          Non ?

          • [^] # Re: Relativisons

            Posté par  . Évalué à 2.

            tout a fait (mais ca n'est pas le cas par default ou avec capsicum)

  • # Arretez SVP de confondre (GNU) LINUX et UN IX

    Posté par  . Évalué à -10.

    Lorsque je lis (en diagonale) la dépèche, je constate (comme de plus en plus souvent) que l'auteur confond allègrement Linux et Unix. Ne mélangeons pas les torchons et les serviettes SVP.

  • # pas compris

    Posté par  . Évalué à 3.

    je n'ai pas compris ce que je ferais de plus avec Capsicum qu'avec Apparmor qui fonctionne déjà très bien (je fait tourner Sk*pe dedans pour qu'il n'accède pas à mes données personnelles)...
    Merci d'avance pour l'éclaircissement!

    • [^] # Re: pas compris

      Posté par  . Évalué à 10.

      À la différence d'AppArmor où c'est l'administrateur système , avec Capsicum, c'est l'application qui restreint elle-même ses droits. C'est plus intéressant pour certains cas car l'application peut nécessiter des droits important au démarrage mais plus après ou un process spécifique de l'application fait des opération sensible et a donc besoin d'être plus limité.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

      • [^] # Re: pas compris

        Posté par  (site web personnel) . Évalué à 4.

        Ce n'est donc pas une protection contre les logiciels malicieux — que ce soit par conception ou suite à une modification volontaire par un pirate — mais contre les failles de sécurité.

        • [^] # Re: pas compris

          Posté par  . Évalué à 10.

          Ce n'est donc pas une protection contre les logiciels malicieux — que ce soit par conception ou suite à une modification volontaire par un pirate — mais contre les failles de sécurité.

          Oui et non. Le but de Capsicum c'est de rendre facile pour une application honnête d'appliquer le Principle of Least Authority. Capsicum ne dit rien en soit des programmes malicieux.

          Cependant, imaginons un instant que l'idée (de bon sens) de respecter le POLA venait à se généraliser (que ce soit à travers l'usage de Capsicum ou d'autres politiques de sécurité permettant aussi cela; tout le monde n'est pas forcé de se mettre d'accord sur un seul outil). Chaque programme annoncerait donc les droits dont il a besoin pour fonctionner, et on pourrait le forcer à ne rien utiliser d'autre (par exemple en le faisant tourner comme processus fils d'un processus ayant exécuté cap_enter). Dans ce cas, le champ d'action des logiciels malicieux est très réduit, puisque s'ils sont trop gourmand en droits, ils sont suspects et on risque de ne pas les lancer tout simplement.

          Aujourd'hui, tous les programmes ou presque tournent avec tous les droits de l'utilisateur. Impossible de différencier les gentils programmes qui font comme ça parce qu'ils ont été codé sous cette hypothèse (par exemple ils incluent un widget "ouvrir un fichier" qui explore gentiment le système de fichier) des vilains programmes qui en profitent abusivement (par exemple ils copient le système de fichier et l'envoient sur le réseau). Si les "gentils" étaient plus économes en droits, on pourrait repérer les vilains plus facilement : l'amélioration des gentils permettrait donc, indirectement, de se protéger mieux de méchants.

          Au risque d'être lourd en répétant la même chose pour la troisième fois (mais je pense que c'est utile car ça reste des idées pas forcément évidentes; par exemple de toute évidence ma remarque pourtant très explicite sur la complémentarité des approches MAC et par capacités n'est pas bien passée), un exemple concret: Windows, dès qu'on lance un programme ou presque qui ne vient pas de Microsoft, nous embête avec une boîte de dialogue pour nous demander si on est vraiment sûr de vouloir l'exécuter. Mais comme il y a ces boîtes tout le temps, on clique sur "oui" sans réfléchir. Si la majorité des programmes windows se mettaient à utiliser un style permettant au système de restreindre finement leurs droits sans nuire à leurs fonctionnalités, il n'aurait pas besoin d'afficher la boîte à chaque fois. Il pourrait se contenter de demander confirmation pour les cas "sensibles" (demande de lecture de fichiers systèmes, d'accès au réseau...), et ne rien dire pour la grande majorité des applications qui n'ont pas besoin de beaucoup de droits (accès à des fichiers temporaires propres à l'application, et c'est tout). La sécurité s'en trouverait alors améliorée, que ce soit pour les programmes "honnêtes" (moins de risque d'erreur) que pour les programmes malhonnêtes (champ d'action plus limité, et avertissements plus visibles).

          • [^] # Re: pas compris

            Posté par  . Évalué à 5.

            Il y a juste un truc que je n'ai pas compris. Si un programme peut récupéré des droits qu'il avait abandonné. Qu'est-ce qui empêche un programme malicieux, lancé en tant que fils d'un autre programme honnête, de commencer par récupérer tous les privilèges et de faire ce qu'il veut?

            « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

            • [^] # Re: pas compris

              Posté par  . Évalué à 10.

              Un programme en mode capacité ne peut pas "récupérer des droits" de lui-même. La seule façon d'acquérir des droits qu'il n'a pas (ou "plus"), c'est si un autre programme (qui a des droits pour le faire) lui passe des capacités supplémentaires.

              Pour un exemple concret, l'exemple du "choix de fichier" : le programme en mode capacité envoie un message à un outil système (ou plutôt de l'environnement de bureau) nommé PowerBox (ou, dans Capsicum, "user rights angel") pour lui demander de proposer un choix de fichier à l'utilisateur. Il lui indique aussi quels droits il réclame sur le fichier ouvert (lecture, écriture, etc.). La PowerBox tourne déjà avec les droits d'accès au système de fichiers, que le programme n'a pas; il propose le choix du fichier à ouvrir à l'utilisateur (en essayant de lui indiquer clairement quels droits il concède sur le fichier choisi), ouvre un descripteur de fichier avec les droits demandés (ce descripteur est précisément une "capacité"), et passe cette capacité au programme initial, qui peut continuer son travail en ayant acquis ce "nouveau droit".

              On peut imaginer la même chose, non dans le cadre d'une interface graphique, mais pour un shell. Actuellement le programme cp a besoin pour fonctionner de l'accès à tout le système de fichier, en lecture comme en écriture; en effet, quand on invoque cp foo bar, il doit transformer le chemin foo en fichier ouvert en lecture et le chemin bar en fichier ouvert en écriture. Plus généralement toutes les commandes qui prennent en argument un chemin doivent avoir les même droits que l'utilisateur sur le système de fichier.
              Mais on peut mettre en place une organisation des programme plus économe en droit. Quand on écrit cat foo > bar, ce n'est plus le programme qui ouvre bar en lecture, mais le shell, qui s'en occupe et passe le descripteur vers bar en sortie standard quand il invoque cat. On peut imaginer une commande cp$ qui prenne en paramètres non pas deux chemins, mais deux descripteurs (un en lecture et un en fermeture). Pour invoquer cette commande il faudrait un shell au courant de cette spécificité, qui aurait par exemple la convention que les arguments de la forme =path et +path (par exemple +/tmp/foo.txt) ne sont pas envoyées sous forme de chaîne de caractères au programme, mais sous forme de descripteurs ouverts respectivement en lecture et en écriture. On invoquerait alors cp$ =foo +bar. Dans ce cas de figure, c'est le shell qui joue le rôle de "programme privilégié transmettant ses droits" (powerbox), et qui permet aux programmes invoqués de mieux respecter le Principle of Least Authority, en étant organisés de façon à nécessiter moins de droits.

              • [^] # Re: pas compris

                Posté par  . Évalué à 2.

                Merci pour cette explication, je n'avais pas bien compris.

                « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

              • [^] # Re: pas compris

                Posté par  . Évalué à 3.

                Je n'aime pas trop cet exemple classique avec les descripteurs de fichiers, imagine que tu remplace 'cp$' par une commande Foo qui interprète le contenu du fichier: comment cette commande donnerait-elle le nom du fichier dans un log/message d'erreur?

                Il faudrait faire: Foo <descripteur de fichier> <nom du fichier> ?
                Pas très pratique..

                Idéalement le 'descripteur du fichier' devrait stocker le nom avec lequel il a été ouvert..

          • [^] # Re: pas compris

            Posté par  . Évalué à 3.

            Sur Android, une application de météo peut demander à l'utilisateur d'accéder à son carnet d'adresses… Et les gens doivent accepter en plus.

            Envoyé depuis mon lapin.

            • [^] # Re: pas compris

              Posté par  . Évalué à 1.

              <i>Et les gens doivent accepter en plus.</i>

              Ah bon? Ils ont un pistolet sur la tempe pour les obliger a valider l'installation de cet application?

              Android te signale que cette application, si TU decides de l'installer pourra acceder a tel ou tel donnees personnel apres TU fais le choix, ou pas de l'installer.

              • [^] # Re: pas compris

                Posté par  . Évalué à 3.

                apres TU fais le choix

                C'est ce qu'il voulait dire, et que malgré ça, les gens acceptent.

                « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                • [^] # Re: pas compris

                  Posté par  . Évalué à 1.

                  apres TU fais le choix C'est ce qu'il voulait dire, et que malgré ça, les gens acceptent.

                  Et?
                  Au mieux les développeurs peuvent aider les utilisateurs raisonnable à sécuriser leur ordinateur (en utilisant un language clair, en faisant attention de minimiser le nombre de popup, etc), mais en final si l'utilisateur est déraisonnable (et qu'il n'y a pas de 'super-utilisateur' pour gérer le bazar), rien ne peut sécuriser un ordinateur.

                  • [^] # Re: pas compris

                    Posté par  . Évalué à 3.

                    C'est ce qu'il dit.

                    « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

                    • [^] # Re: pas compris

                      Posté par  . Évalué à 3.

                      Merci de m'avoir compris. Ma formulation était ambiguë :D

                      Envoyé depuis mon lapin.

              • [^] # Re: pas compris

                Posté par  . Évalué à 2.

                Quand on cherche une application, et que les 10 premières demandent toutes des permissions qui semblent inutiles, on est plus hésitant à regarder la 11ème. Un utilisateur lambda ira encore moins loin et ne prendra plus que la première, la fois d'après.

  • # comparaison avec Kauth ?

    Posté par  (site web personnel) . Évalué à 4.

    J'ai l'impression que ça ressemble a ce que propose le framework Kauth (Kernel Authorization) de Apple (donc disponible dans mac os X) et libéré en open source (porté sur NetBSD)

    j'ai raté quelquechose?

    • [^] # Re: comparaison avec Kauth ?

      Posté par  . Évalué à 7.

      Je ne connais pas kauth, mais un des chercheurs principaux du projet Capsicum, Robert Watson, le connaît relativement bien, puisqu'il expliquait en 2006 que kauth n'était pas assez flexible pour implémenter le modèle MAC sur lequel il travaillait à l'époque.

      J'ai trouvé une discussion plus récente sur kauth, NetBSD et capsicum, c'est ce message de David Young, mais il n'est pas très explicite:

      It is just my personal opinion that it's most desirable to have in NetBSD a capabilities framework such as Capsicum, which need not be and should not be implemented in terms of kauth.

      Si tu veux plus d'informations à ce sujet, le mieux est sans doute d'aller poser la question sur la mailing-list Capsicum.

  • # SELinux can do that !

    Posté par  . Évalué à 2.

    SELinux permet déjà de contrôler finement les privilèges d'une application, du coup, quels sont les avantages de capsicum par rapport à cette solution ?
    linuxplumbersconf.org/2009/slides/dan-walsh-selinux-sandbox.pdf

    • [^] # Re: SELinux can do that !

      Posté par  . Évalué à 3.

      La différence c'est pas que dans SELinux l'admin donne alors qu'avec capsicum le développeur demande ?

    • [^] # Re: SELinux can do that !

      Posté par  . Évalué à 5.

      L'auteur a déjà répondu à cette question:

      pour les deux approches MAC (Seatbelt de Mac OSX et SELinux), ils se plaignent d'un manque de flexibilité, d'une gestion de droits au final moins fine qu'avec Capsicum (par design pour Seatbelt, et par difficulté pour SELinux), et surtout d'un manque de flexibilité dynamique : les politiques d'accès doivent être fixées avant le lancement du programme et ne peuvent pas évoluer dynamiquement, contrairement à la gestion des droits dans un système à capacité.

      « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

    • [^] # Re: SELinux can do that !

      Posté par  . Évalué à 4.

      Le mécanisme de SELinux est un mécanisme au niveau de l'OS qui permet de limiter les capacités du programme avant son lancement.

      Capsicum lui se place au niveau de l'application afin de faciliter l’implémentation du Principle of Least Authority. Il consiste a séparer un gros programme en plusieurs morceaux, tout en réduisant au maximum les capacités des morceaux les plus dangereux. Si jamais ce morceau dangereux venait a être compromis, il ne pourrait pas faire beaucoup de mal.

      Un programme comme Chromium utilise déjà le Principle of Least Authority. Des programmes sensibles tels que OpenSSH l'utilisent aussi, etc. Je crois même qu'OpenBSD est allé jusqu’à l'appliquer a Apache 1.3 .

      La ou capsicum est intéressant c'est sur la facilité pour l'utiliser sur un programme appliquant déjà ce principe (seulement 100 lignes de plus ajoutées a Chromium qui pourtant est un logiciel très complexe) tout en offrant plus de contrôle qu'avec les solutions déjà existantes. Pour les programmes n'appliquant pas ce principe, il n'y a besoin d'aucun changement dans le code et ils fonctionneront comme avant!!

      Donc Capsicum ne change rien pour les programmes existant, tout en permettant d'appliquer plus facilement le Principle of Least Authority, et de gérer de manière plus fine les droits sur les programmes. Il permet aussi de passer les capacités d'un programme a l'autre (l'article Wikipédia anglais Confused Deputy Problem est assez éloquent).

      Donc les systèmes tels SELinux (Mandatory Access Control) permet de limiter les droits du programmes avant sont lancement (a priori), alors que Capsicum permet au programme de mieux gérer les droits lors de l’exécution (a posteriori).

      J’espère avoir été assez clair.

  • # Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

    Posté par  (site web personnel, Mastodon) . Évalué à 2.

    Salut,

    cette solution permet-elle de restreindre les droits utilisateurs simples (1)? Par exemple si je veux lancer un programme en m'assurant que ce problème ne puisse pas du tout lire dans le système de fichier (même les fichiers appartenant à l'utilisateur qui fait tourner le programme), est-ce possible?

    Ou bien cela permet simplement de donner quelques droits supplémentaires à un utilisateur (qui sont normalement réservés à root), mais pas tous (2)?

    Je m'intéresse justement en ce moment à faire la première chose (1) en particulier. Quelles sont les solutions existantes (Capsicum ou autre) capables de faire ce genre de restrictions sous Linux?

    Je me suis bien sûr intéressé aux "capabilities" du noyau Linux mais tout ce que je lis (par exemple http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt ) semble indiquer que cela ne permet que la seconde fonctionnalité (2) que j'ai citée plus haut.

    Je suis intéressé par tout lien sur la chose ou points de départ pour une recherche. En particulier je souhaite ne pas avoir à modifier un kernel (donc en fait Capsicum, qui m'intéresse dans le concept et peut-être dans l'avenir, n'est cependant pas intéressant pour moi à court terme tant que ce n'est pas un élément de base de Linux).

    Merci pour ce sujet intéressant en tous cas. :-)

    Film d'animation libre en CC by-sa/Art Libre, fait avec GIMP et autre logiciels libres: ZeMarmot [ http://film.zemarmot.net ]

    • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

      Posté par  (site web personnel) . Évalué à 6.

      question pour qq un comme moi, ça :p

      1) cette solution permet-elle de restreindre les droits utilisateurs simples
      2) donner quelques droits supplémentaires à un utilisateur (qui sont normalement réservés à root), mais pas tous

      C'est marqué au dessus : le développeur d'une application pourra choisir, avec capsicum : le but n'est pas de resteindre les droits, mais d'implémenter une solution pertinente (et facile d'usage pour les dev, voir le "portage facile") afin d'atteindre un but de séparations conforme à l'esprit POLA (coir ci dessus).

      3) _ si je veux lancer un programme en m'assurant que ce problème ne puisse pas du tout lire dans le système de fichier_
      Dés éléments de réponses sont apportés ci dessus. Le chroot par exemple (mais sa mise en oeuvre en le fortifiant un peu n'est pas aisé, du moins, moins que l'utilisation des solutions implémentées par des distributions). SELinux permet cela. AppArmor également.
      Souvent le plus simple est d'utiliser les ... utilisateurs de ton système. Ainsi par exemple créer un utilisateur "webuser" qui ne fera que lancer chromium... Ce chromium là ne pourra alors lire ton dossier /home de ton utilisateur courant, par simple droit sur ces dossiers.

      4) n'est cependant pas intéressant pour moi
      Si car c'est exactement la cible : avoir par défaut un comportement du "plus petit droit possible", donc, par rebond, que l'utilisateur n'est pratiquement pas à s'en soucier. Même pas besoin d'avoir une commande spécifique préalable pour lancer un programme.

      Bref, relis bien cette dépêche, et regarde du côté de la séparation des droits basiques, des limites que l'on peux attribuer, puis des ajouts spécifiques. Capsicum viendra ensuite (peut être) en complément, et par défaut, sans qu'il y ai besoin d'une intervention de l'administrateur. A aucun moment capsicum ne prendra leur place, même s'il s'avère que des possibilités se chevauchent. Puisque toutes les autres solutions demandent l'intervention de l'admin, donc TA configuration du système. Tandis que Capsicum offre de nouveaux outils pour une bonne pratique possible et aisée, au service des développeurs.

      Exemple IRL : chromium a besoin pour le moment du bit suid pour pouvoir faire son sandboxing. Ce qui veux dire qu'une faille bien exploité, mettons dans un flash, pourra peut être avoir les droits root sur ta machine. Faille dans Flash, puis dans chromium = root facile. Egal, pakool :p. C'est un exemple typique de opensource vs closed-source, par ailleurs. S'il est plus facile de repérer des failles des failles dans un programme open-source, celles ci sont corrigées plus vite. Tandisque s'il est plus difficile de repérer des failles dans un programme closed-source, ces failles resteront bien plus longtemps en status zero day... Et hop, un troll de tué. L'open-source n'est pas plus sécurisé en général, mais il permet une meilleure sécurisation en particulier.

      Voilà, j'espère ne pas avoir dit de bêtise, et avoir un poil éclairé tes questions.

      ps : je profite de ce commentaire pour dire MERCI pour cette dépêche, claire et passionnante.

    • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

      Posté par  . Évalué à 3.

      Je me pose un peu les même questions.

      Personellement j'apprécie beaucoup l'approche des capabilities déjà existantes, qui permettent d'agir sans passer par le code source (celui qui fait le code n'est pas forcément celui qui met les autorisations). Et cela agis par augmentation des privilèges : on exécute l'application avec un utilisateur sans aucun droit et l'appli n'a que les droit qui lui sont donné par les capabilities. De plus les capabilities peuvent être définis en amon au sein même du projet contrairement à SELinux (AppArmor, TOMOY, etc) qui est vraiment lié à une installation donnée.

      L'exemple que j'aimais bien c'est ping, qui est souvent exécuté avec le bit setuid root ! Si on lui donne la capabilities CAP_NET_RAW (et peut être une autre), on peut lui enlever ce bit et c'est déjà pas mal je trouve.

      Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

      • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

        Posté par  . Évalué à 4.

        Les 'POSIX capabilities' sont beaucoup plus grossières que ce qu'on considère comme une capacité dans les "systèmes à capacités". Cf. par exemple la section à ce sujet de ce document :

        At the level of detail that we typically care about (individual files, programs, and so on) resources are created and destroyed all the time. There is a bounded set of POSIX capability flags only because they do not express authorities at this level of detail. For example, one of the POSIX capability flags is CAP_CHOWN, which represents the power to change the ownership of any file on the entire system. Just as with the granularity of subjects, we can consider this a granularity issue with respect to resources, where the ability to dynamically create new resources is the clear dividing line betwen "fine-grained" and "coarse-grained".

        Bref, on peut voir ça comme un pas dans la bonne direction, mais le niveau de finesse de gestion des droits (et donc le respect du POLA, et donc la sécurité) est nettement moins bon.

        • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

          Posté par  . Évalué à 1.

          Le problème n'est pas la finesse (j'arrive encore à savoir que 24 et plus petit que 60), mais la manière de l'appliquer et la manière dont ça s'utilise sur le système (on lance l'appli avec quoi comme utilisateur ? un utilisateur pleins de droits ou un utilisateur sans droit ?).

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

            Posté par  . Évalué à 6.

            Non, ce n'est pas 24 contre 60, c'est 24 contre une infinité organisée selon 60 modes opératoires différents.

            Un processus donné peut gérer 24 (enfin plutôt 30 je crois mais bon) 'POSIX capabilities' différentes, par exemple CAP_CHOWN qui lui permet d'appeler chown sur n'importe quel fichier.
            Un processus peut avoir accès à un nombre non borné de descripteurs de fichiers (et plus généralement de ressources : mémoire partagée, sockets, etc.) différentes. Chaque ressource donne accès à un objet du système, et à cet accès sont associé, en mode capsicum, un petit nombre de droits (idéalement, un seul). Par exemple un descripteur de fichier enrichi du flag CAP_FCHOWN représente le droit d'appeler fchown sur le fichier en question, et pas un autre.

            Quand je parle de finesse ce n'est pas seulement plus d'appels systèmes pris en compte, ou le fait de tenir compte aussi des autres espaces de noms globaux. C'est la possibilité que chaque ressource tenue par le programme représente un droit différent. Il s'agit d'autoriser la modification des droits de tel et tel fichier et aucun autre (tant que, pendant le déroulement du programme, un autre programme ne lui transfère pas dynamiquement le droit vers des fichiers supplémentaires), au lieu de choisir entre "accès à chown ou non".

    • [^] # Re: Restreindre les droits utilisateurs ou avoir un utilisateur avec certains droits admins?

      Posté par  . Évalué à 0.

      A noter que RSBAC (rsbac.org) permet d'assigner ou non ces capabilities (capsicum, android ou "stock linux") par programe, role, utilisateur plutot que de modifier dans l'appli.

      Evidement c'est legerement moins flexible puisque tout toute l'appli perd la capability par exemple, mais c'et aussi beaucoup plus simple à utiliser en tant qu'utilisateur et non programmeur.

      Il y a aussi rsbac_jail qui permet de faire le même genre de choses sans capsicum, cad sans les capabilities additionelles, mais on peut preciser si on veut que l'app qui tourne ai accès au reseau ou non, au sockets unix, syslog, etc etc.

      Typique:

      rsbac_jail <-flag pour socket unix -flag pour ipv4 -flag pour avoir le droit de binder sur telle ip, -flag pour telle capability -flag pour tel autre droit, ... > monservice

  • # Bravo pour cette dépêche

    Posté par  . Évalué à 3.

    J'arrive un peu en retard pour dire bravo a l'auteur de la dépêche qui a bien réussi a expliquer de manière suffisamment simple un sujet complexe. Bon apparemment certains commentaires montrent que c’était encore complique, mais on ne peut pas non plus simplifier a l’extrême les choses extrêmement complexe.

    Et merci de nous avoir fait découvrir Capsicum, cette solution a l'air très prometteuse car avec elle il n'y a pas besoin de modifier les programmes qui ne veulent pas fonctionner selon le POLA, alors que ceux qui sont intéressés nécessitent peu de changements tout en obtenant une gestion plus fine de ces capacités.

    J'ai juste une question sur le Confused Deputy Problem, dans le cas décrit sur Wikipedia.

    Étant donné les appels UNIX « classiques », comment est ce que le logiciel client du service de compilation peut passer un descripteur de fichier au service de compilation? Je vois bien comment le transfert de capacité peut se faire dans le cas d'un fork(), mais comment cela se passe-t-il pour des processus sans liens directs?

    Merci.

    • [^] # Re: Bravo pour cette dépêche

      Posté par  . Évalué à 3.

      Merci pour l'avis, ça fait plaisir. Merci aussi pour avoir rédigé une réponse sur la différence entre MAC et capacités, j'espère que ton explication passera mieux que ce que j'ai essayé de faire dans la dépêche.

      Pour répondre à ta question, on peut utiliser les sockets unix pour passer des descripteurs de fichiers. Cf. cette question ou ce billet. Bien sûr, si on voulait implanter un système de capacités complet, on ajouterait sans doute des facilités de passage de message pour rendre plus directe cette opération extrêmement courante.

      • [^] # Re: Bravo pour cette dépêche

        Posté par  . Évalué à 2.

        Merci pour la réponse. Ça commence a être sacrement « sioux » ces appels systèmes! Je ne les connaissais pas.

        En plus je venais juste de lire la réponse dans le PDF "Capsicum: practical capabilities for UNIX": "Capabilities may be delegated from process to process in a granular way in the same manner as other file descriptor types: via inheritance or message-passing."

        Mais j'aime mieux ta réponse qui est bien plus concrète.

  • # et le premier à l'utiliser est hast

    Posté par  (site web personnel) . Évalué à 3.

    Bravo pour la dépèche.

    Le premier utilisateur de capsicum dans -current :
    http://svn.freebsd.org/viewvc/base?view=revision&revision=219847

    les pixels au peuple !

  • # Et Policykit là-dedans

    Posté par  . Évalué à 0.

    Tout d'abord bravo pour cette dépêche !
    J'aimerais bien que quelqu'un explique au néophyte que je suis comment se situe capiscum par rapport à polkit. Du peu que j'ai compris de polkit, un programme demande à polkit une autorisation (par envoi de message dbus) pour effectuer un certain type d'action (une capacité ???), ce qui me semble assez similaire dans le principe, non ?

    • [^] # Re: Et Policykit là-dedans

      Posté par  . Évalué à 3.

      PolicyKit reconnaît le fait que le système Unix habituel ne permet pas d'appliquer efficacement le Principle of Least Privilege, et ça fait un point commun avec Capsicum.

      Il est plus orienté vers un accès à des droits supplémentaires pour un utilisateur, le genre de chose qui demanderait des droits root d'habitude. Capsicum peut faire ça, mais il est aussi (surtout ?) pensé pour restreindre les droits utilisateurs au strict minimum. C'est faisable avec le modèle PolyciKit, en partant d'un utilisateur anonyme sans droit qui dialogue par PolicyKit pour obtenir plus de droits, mais c'est sans doute pas vraiment prévu pour en l'état donc moins pratique. Plus généralement, Capsicum permet de limiter facilement les droits existant au strict minimum, alors que PolicyKit décrit seulement comment obtenir plus de droits (ce que Capsicum permet aussi).

      Au niveau du fonctionnement, PolicyKit n'est pas un nouveau modèle d'accès, implémenté au niveau du noyau ou de bibliothèques de base. C'est seulement un serveur de messages qui est pensé pour faire dialoguer des applications sans droits et des applications avec droit, pour demander aux applications avec droits de faire des choses pour les sans droits (ce qui revient à leur "prêter" ponctuellement ce droit). C'est donc plutôt une question d'organisation du transfert de droit, qu'un choix technique sur le mécanisme de droit d'accès. Dans un système à capacités, il faudra aussi de tels mécanismes d'organisation, et les solutions retenues habituellement utilisent, comme PolicyKit, le passage de messages. Par exemple, la situation du dialogue de choix d'un fichier décrite dans la news est typique d'un dialogue entre un programme sans droits (Sur le système de fichier) et un utilitaire système privilégié (le programme de choix de fichier), qui fonctionne par passage de message.

      Par contre, au-delà de l'aspect 'passage de message', la façon dont PolicyKit et les systèmes de capacités représentent les droits est très différente. PolycyKit utilise un système tout à fait classique de style "matrice d'accès" : on dit "je suis le SUjet, je veux faire telle Action sur tel Objet", et Polycikit autorise ou non. La programmation de système utilisant Policykit se fait donc en se posant des questions comme "qui a le droit d'accéder à tel Objet ?", "Quelles sont les Actions que l'on autorise pour tel Sujet" ? En particulier la gestion des sujets est assez grossière, c'est essentiellement l'utilisateur au sens des systèmes Unix, on pourrait faire plus fin (par exemple on peut temporairement utiliser un processus donné à faire une action donnée en envoyant à un système privilégié un message du style "maintenant si on te demande l'autorisation pour le pid truc, tu acceptes", et en changeant d'avis au bout d'un moment) mais ce serait, dans la plupart des cas, galère à programmer.
      Avec les systèmes à capacités, le point de vue sur la gestion des droits est fondamentalement différent. Les droits et les actions sont couplés, et les processus se les passent entre eux selon le besoin, sans passer par un "système de droit" intermédiaire. On se demande donc "de quel droit tel processus/programme/système/utilisateur va-t-il avoir besoin ?", on les lui donne, et après c'est à lui de les répartir avec les autres processus avec qui il est en contact. La gestion des droits est donc naturellement plus fine et plus dynamique, mais aussi moins structurée (d'est ensuite aux applications d'utiliser des patterns de transfert de droits qui suivent une politique haut-niveau donnée). La question de "tel Sujet a-t-il le droit d'utiliser cette Capacité/Action ?" n'a pas de sens : soit il possède la capacité et alors il lui suffit de l'activer pour effectuer l'action, soit il ne la possède pas et il ne peut même pas essayer.

      • [^] # Re: Et Policykit là-dedans

        Posté par  . Évalué à 1.

        Plus généralement, Capsicum permet de limiter facilement les droits existant au strict minimum, alors que PolicyKit décrit seulement comment obtenir plus de droits (ce que Capsicum permet aussi).

        Je ne pense pas que Capsicum permette d'obtenir plus de droits. C'était justement le reproche fait a un des frameworks de sécurité étudié par l'équipe Chrmoium: l'application pouvait parvenir a regagner des droits. Ici, on peut transférer des capacités d'un processus a un autre, mais pas "augmenter" les droits existants.

        Et en relisant, je pense que c'est ce que tu voulais dire.

        • [^] # Re: Et Policykit là-dedans

          Posté par  . Évalué à 2.

          Ici, on peut transférer des capacités d'un processus a un autre, mais pas "augmenter" les droits existants.

          Oui, quand je parle d'"obtenir plus de droits" dans ce contexte, c'est au sens indirect. Avec Policykit, on discute avec un processus plus privilégié pour qu'il nous "prête" temporairement ses droits en effectuant des actions pour nous. Dans un système à capacités, on peut discuter avec un processus plus privilégié (ayant plus de capacités) pour qu'il nous transfère certaines capacités.

          Plus généralement ce schéma (discuter avec un privilégié pour qu'il effectue des actions pour nous ou nous en donne le droit) est utilisé dans de nombreux systèmes de droits, puisque c'est un des plus flexibles, l'application privilégiée étant libre de gérer l'accès (les "prêts") comme elle le souhaite, indépendamment de toute politique de contrôle d'accès. C'est aussi celui utilisé par Chromium dans la version seccomp par exemple.

          Une remarque : le côté obscur de cette méthode est que les politiques de contrôle d'accès ne peuvent pas empêcher deux applications qui communiquent de se "prêter" leurs droits (volontairement ou non, on peut exploiter un bug de l'application privilégiée). Une fois qu'on en est là, la seule façon de "contrôler" la sécurité du système est de s'assurer que ces processus ne peuvent pas entrer en communication. Dans ce contexte, les systèmes par capacités pures sont très intéressants, puisque chaque référence à un autre objet du système est par définition une capacité : on peut savoir avec quels objets/processus un agent donné peut entrer en contact en regardant uniquement ses capacités. Pour savoir si un agent donné pourra un jour communiquer avec un autre agent (pour lui extorquer des droits par exemple), on considère les capacités comme les arrêtes d'un graphe entre agents, et on regarde s'il y a un chemin entre ces deux agents. Les systèmes "à autorité ambiante" sont généralement aussi des systèmes "à communication ambiante" où n'importe qui peut parler à n'importe qui, et dans ce cas là on ne peut rien dire.

  • # Erreur dans les sources

    Posté par  . Évalué à 2.

    Je suis un peu en retard mais il semble y avoir une erreur présente dans les sources (et je ne sais pas trop comment la signaler =S) :

    if (lc_limitfd(STDOUT_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0)
        error("lc_limitfd: unable to limit STDIN_FILENO");
    

    devrait probablement être (noter le STDOUT_FILENO dans le message d'erreur) :

    if (lc_limitfd(STDOUT_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0)
        error("lc_limitfd: unable to limit STDOUT_FILENO");
    

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.