Inglorious Astar

Security by design before it was cool

The same ... but different ... but still the same

Public cible :
RSSI
-
Temps de lecture :
15
min

Depuis l'entrée en vigueur du RGPD et "l'explosion" de l'IoT, on entend régulièrement parler de "privacy by design" et de "security by design".

L'idée générale demeure simple : payer un peu au début pour ne pas payer beaucoup, d'un seul coup, plus tard.

L'agitation marketing autour de ces notions laisse penser qu'il s'agit de nouveaux concepts "bleeding edge", que tout est à inventer, etc.
Pas exactement ...
Sans aller jusqu'à se moquer au point de dire que ce que l'on appelle "security by design" pourrait se traduire par "le bon sens" ou encore "faire correctement son job", il existait une littérature déjà riche sur le sujet, bien avant l'IoT et le RGPD.

Indéniablement, le privacy by design a ajouté et précisé des notions du security by design. Mais nous allons aujourd'hui nous intéresser à ce que ce concept apportait déjà avant d'être un buzzword.

Un concept bien plus mature qu'on ne le croit

On a coutûme de renvoyer les fondements du concept de security by design à la publication d'un papier de 1974, par Saltzer et Schroeder, intitutlé The Protection of Information in Computer Systems.
Il s'agit d'un des articles les plus cités de tout le domaine. Il a notamment le bon goût de fixer 8 principes clés qui s'appliquent à la conception (design) d'un projet/outil/systeme pour garantir sa sécurité.
Le 8ème va décomplexer quelques RSSI.

Minimalisme (Economy of mechanism)

Intro

Conservez vos mécanismes aussi simples et légers que possible. Principe que l'on retrouve de nos jours sous l'acronyme KISS.
Toute complexité superflue augmente les chances de commettre une erreur d'implémentation et diminue les chances de s'en rendre compte facilement. Quelques acteurs du monde de la sécurité se revendiquent de ce principe (comme Alpine Linux et son slogan : "Small Simple Secure"), mais la majorité nous ont habitué à de grosses usines à gaz.

L'implémentation de ce principe implique une certaine culture de la "sobriété" numérique : éviter de dire oui au service marketing qui veut investir dans la dernière cafetière connectée. L'utilité est minime et vous ignorez le niveau de sécurisation (généralement l'IoT c'est 0). Ce serait dommage d'exposer le SI aux attaques juste pour que Michel attende 2min de moins pour son café.
La culture de la sobriété a des vertus importantes en termes de sécurité et même de productivité (éviter les KPI long à produire et jamais lus par personne). En revanche, sans une certaine "plasticité" de la structure, la sobriété peut aller à l'encontre de l'innovation. Il y a effectivement des sujets où il faut se lancer sans avoir tout le recul qu'on aimerait si on ne veut pas louper le coche.
Sujet difficile à maitriser donc.

Sûreté par défaut (Fail-safe defaults)

Dans l'utilisation courante d'un système, d'un outil, d'un processus, il y aura forcément des erreurs et des oublis. Ce principe nous dit que, sachant cela, il faut se débrouiller pour que l'état par défaut soit celui de la sécurité.

Par exemple pour une politique de gestion des accès, faut-il mieux se poser la question "ai-je une bonne raison d'autoriser cet accès ?" ou bien la question "ai-je une bonne raison d'interdire cet accès ?".
On sait qu'il y aura des oublis, donc du point de vue de la sécurité, il vaut mieux avoir oublié d'octroyer un accès (faible impact et ça se détecte vite) que d'avoir oublié d'en interdire un (gros impact potentiel et difficile à détecter).
La sûreté par défaut nous dit donc de tout interdire par défaut (doctrine fail safe) et de faire des exceptions pour les accès nécessaires (c'est notamment le principe qu'on applique pour les pare-feux).
Le pire étant d'essayer de mélanger à la fois une politique d'octroie d'accès et de restriction.

Un concept de secure coding dit que "tout ce qui provient de l'extérieur de l'application doit être considéré comme hostile" et donc devant faire l'objet d'un assainissement avant toute utilisation.
Cette recommandation précise aussi que si une entrée n'est pas valide, il faut la rejeter plutôt que d'essayer de la transformer en une donnée valide. Ça c'est un autre exemple de fail safe (rejeter une entrée à tort c'est pas dramatique, mal transformer une donnée ça peut être bien plus grave).

On entend parfois aussi parler de "fail secure".
Il y a en fait une opposition fail safe VS fail secure mais qui appartient au monde du contrôle d'accès physique (oui ... les portes quoi).
Fail safe : ça veut dire qu'en cas de coupure de courant la porte peut être ouverte (le secours peuvent donc entrer).
Fail secure : ça veut dire qu'en cas de coupure de courant la porte ne peut pas être ouverte (les actifs demeurent protégés de l'extérieur).
Précision : dans les deux cas, la porte s'ouvre de l'intérieur vers l'extérieur, rassurez-vous les gens peuvent sortir s'il y a le feu.
Pour l'informatique on utilise que le terme fail safe mais pour le coup a plutôt le sens du fail secure du monde de la serrurerie.

Arbitrage instantané (Complete mediation)

Intro

Toute demande d'accès à un objet doit être préalablement soumise à un contrôle des permissions par l'autorité d'IAM. Jusqu'ici ça va, hormis quelques cas pathétiques, c'est le schéma que l'on observe le plus souvent.
Mais ce principe vise surtout à dire que les demandes d'accès doivent être en temps réel, et non pas basées sur un cache, de sorte à ce que tout changement dans les permissions soit immédiatement répercuté opérationnellement.

Ce principe pose aussi les bases de ce qui se nomme aujourd'hui le "Zero Trust" puisqu'il prévoit que l'IAM puisse se faire à distance et que ceci implique donc des moyens d'assurer l'authenticité d'une requête.
Aujourd'hui on parlerait donc d'authentification mutuelle (le client s'authentifie vis à vis du serveur et vice versa), ce qui se fait généralement au travers de certificats x509, de clé PGP, de clé SSH, etc.

Pour résumer, chaque fois qu'un accès à un objet est requis, on doit arbitrer sur la validité et la légitimité de la demande.

Conception ouverte (Open design)

Intro

Reprise du célèbre principe de kerckhoff : "l'adversaire connait le système". Ce point rappelle qu'on évalue toujours la sécurité d'un système en postulant l'adversaire aussi informé que possible, exception faite des secrets (clés ou mots de passe). Et non le code source d'un algorithme ne peut pas être considéré comme un secret. Un secret c'est quelque chose qu'on traite comme tel, donc qu'on garde protégé chez soi et certainement pas qu'on distribue dans un logiciel ou un équipement, aux 4 coins du monde.

Partant du principe que l'adversaire connait le système, le rendre public assure de se donner le maximum de chances de découvrir les vulnérabilités avant l'adversaire puisque n'importe qui peut l'auditer.
Ceci participe aussi à l'établissement de la confiance puisque n'importe quel utilisateur peut se convaincre de la sécurité de l'outil avant de l'utiliser.

Bien que ce principe n'ait toujours pas fortement pénétré l'écosystème informatique (il y a encore une majorité de produits de sécurité dont les sources ne sont pas accessibles), il est incontournable dans le milieu du chiffrement. Aujourd'hui personne n'oserait raisonnablement utiliser une solution cryptographique basée sur un "algo maison en boîte noire".

On comprend bien que ce point rentre en contradiction directe avec les modèles économiques de la vente de logicielle. C'est un sujet délicat, pour autant, il est peu probable que la réalité décide de changer juste pour faire plaisir au capitalisme.
Donc, force est de constater (avec un brin d'insolence) qu'utiliser un outil de sécurité (généralement placé au coeur du système, avec accès à tout le SI) dont le code n'est pas open source (Active Directory, antivirus commercial, pare-feu commercial, ...) ne respecte pas l'état de l'art du concept de security by design.

Séparation des privilèges (Separation of privilege)

Intro

Ce concept postule qu'il est souhaitable qu'un système n'octroie pas un accès en se basant sur une unique condition. C'est le cas par exemple pour les missiles qui ne peuvent être lancés que si deux personnes distinctes activent leur clé.
Plus proches de nous, ce concept vous rappelera probablement l'authentification à double facteur (mot de passe + SMS, mot de passe + clé SSH, mot de passe + OTP, ...). Dans ce cas là, bien qu'il y ait deux clés, c'est généralement la même personne qui les possède. Mais il y a bien deux malversations distinctes à mener pour un adversaire voulant dérober l'accès.

Le fondement de ce principe est qu'en doublant le nombre de clés nécessaires, on fait s'effondrer les probabilités qu' un accident/une brèche/une manipulation unique suffisent à compromettre le système. Chaque secret étant géré et protégé de manière différente, soit parce que des entités distinctes les possèdent soit car ils diffèrent par leur nature, l'effort et les compétences nécessaires à leur compromission conjointe se démultiplient.

Typiquement, aujourd'hui il est admis que tout point unique de défaillance (SPOF) de votre réseau devrait implémenter ce principe (l'admin du domaine, l'accès à la banque, ...).

Moindre privilège (Least privilege)

Est-il encore besoin de le présenter ? Le principe de moindre privilège est bien connu et assez transparent à expliquer. Quand un processus, ou un utilisateur, dispose uniquement des permissions strictement nécessaire à ses tâches, cela réduit les dommages en cas d'erreur ou de compromission.

Ce concept est très proche du principe de sûreté par défaut : de base on interdit tout et on n'octroie que les privilèges justifiés.
Il existe plusieurs bénéfices auxquels on ne songe pas forcément. Par exemple, quand tous les processus s'exécutent avec le minimum de privilèges requis, si l'on observe un problème avec une ressource, le nombre d'éléments à auditer, pour en comprendre l'origine, est minimal.

Une implémentation intelligente de ce principe a conduit aux mécanismes de "drop" de privilèges qu'utilise, entre autres, apache ou nginx. Ils sont lancés avec les privilèges de root le temps d'aller lire les clés TLS, qui sont conservées en mémoire, puis la portion qui sert le code du site Web s'exécute avec les droits restreints de www-data.

Moindre mutualisation des mécanismes (Least common mechanism)

Intro

Plus une ressource ou un mécanisme est utilisé par des entités nombreuses et différentes (utilisateurs, serveurs, prestataires, ...), plus la vraisemblance d'incidents augmente (intrusion, compromission, erreur humaine) et plus les impacts de ces incidents sont importants (puisque de multiples entités en dépendent).

Par exemple, mettre en place un partage de fichiers entre les utilisateurs s'entend. Même s'ils sont nombreux, ils forment une entité relativement homogène et le cas d'usage est unique: mettre à disposition et consulter des documents.
Si maintenant quelqu'un propose que le serveur X aille automatiquement piocher son fichier de configuration sur le serveur de partage, que le serveur Y dépose automatiquement un fichier CVS sur ce partage et que le serveur Z le consomme depuis cette même place ... on se retrouve avec un problème de trop grande mutualisation :

  • Si un utilisateur efface par mégarde le mauvais fichier, les serveurs X et Z ne fonctionnent plus
  • Si un utilisateur modifie le fichier de configuration de X, il peut modifier son fonctionnement
  • Si un adversaire compromet le serveur Y, il peut déposer des fichiers malveillants sur le partage pour piéger des utilisateurs ou bien le serveur Z
  • etc.

Bien que "mutualisation" soit plutôt un terme connoté positivement dans un SI, ces exemples montrent qu'il peut être une source de vulnérabilité.
Entendons nous bien, l'objectif n'est pas d'avoir un outil différent par machine. La multiplication des outils dans un SI est aussi une source de vulnérabilité (perte de visibilité, mauvaise interopérabilité, processus lourds, ...). On peut utiliser le même outil pour des acteurs différents mais ils doivent utiliser des instances dédiées de cet outil (comme le fait de segmenter son réseau en plusieurs Active Directory distincts pour éviter que le vieux Windows Server 2003 soit dans le même AD que les WS 2019).
Autant que possible, essayer de mutualiser seulement entre des acteurs de criticité comparable. Quand ce n'est pas possible, limiter autant que possible le nombre d'acteurs impliqués.
Le contre exemple absolu étant celui du point unique de défaillance (SPOF) que l'on cherche à tout prix à éviter dans une infrastructure.

Acceptabilité des usagers (Psychological acceptability)

Intro

Ce qui nous amène à un des points les plus intéressants. Si vous concevez des mesures de sécurité qui nuisent à la facilité d'utilisation, il y a une limite au delà de laquelle le "consentement à la loi" des utilisateurs disparait et où ils tenteront d'outrepasser vos mesures car ils les jugeront abusives. Donc en concevant des mesures de sécurité trop coericitives, vous transformez des acteurs de la sécurité en des sources de menace :

  • en imposant trop de mots de passe différents, qui changent régulièrement, sans fournir de vault, vous vous retrouvez avec des utilisateurs qui stockent leurs mots de passe dans un cahier ou sur un post it
  • en imposant des contrôles d'accès physiques trop redondants, vous vous retrouvez avec une porte à accès restreint bloquée en position ouverte par un caillou
  • en restreignant l'installation de programmes sans avoir de processus facile d'exception, vous vous retrouvez avec des connexions de clés USB personnelles contenant des programmes portables

Bien des problèmes viennent du manque de prise en compte de ce principe.
Il n'est pas possible de concevoir un système de sécurité où les gens sont le problème. Un système qui marche tant que les utilisateurs agissent comme vous le souhaitez porte un nom : ça s'appelle un système qui ne marche pas. L'utilisateur n'est pas une variable, c'est une donnée.

La meilleure sécurité c'est celle qui ne se voit pas. En tant que RSSI, vous ne devez pas passer des nuits blanches parce que vous avez renoncé à une mesure de sécurité car il n'était pas possible de la faire accepter au personnel. C'est un choix pragmatique qui se justifie.

Imposer des mesures de sécurité qui gènent l'activité des usagers peut finir avec un bilan négatif sur la sécurité à cause du phénomène que nous avons décrit. Ça ne veut pas dire qu'il faut en rester là. Il y a souvent de la marge de manoeuvre au niveau de la sensibilisation des utilisateurs, d'une part, et de l'automatisation des mesures de sécurité, d'autre part, afin qu'elles perturbent au minimum les tâches.
Par exemple, les airbag des voitures apportent une sécurité importante et ne perturbent en rien l'usager, leur adoption a été rapide. La ceinture de sécurité, en revanche, implique un changement notable dans les habitudes des usagers. Même si son utilité est avérée, son adoption a été longue en raison de ce principe, il a fallu légiférer, mettre des alarmes quand elle n'est pas attachée, etc.
Ce que vous devez viser c'est plus l'airbag que la ceinture de sécurité.

Et depuis ?

Vous pourriez être tenté d'objecter que, depuis 1974, le sujet a quand même dû évoluer un peu.

Effectivement.

On a ajouté plusieurs principes supplémentaires (qui font plus ou moins consensus). Mais ce qui est en fait remarquable c'est le peu de transformation qu'a subi ce concept, tant son socle de départ était solide (on ne peut pas en dire autant de concepts comme le Zero Trust par exemple avec une définition différente par personne).

Voyons quelques principes ajoutés depuis.

Défense en profondeur (Defense in Depth)

Le plus célèbre probablement. Ce principe postule qu'aucune ligne de défense n'est infranchissable et qu'une politique de sécurité efficace doit donc miser sur leur multiplication.

Il y aura toujours un pirate qui arrivera à créer un malware indétectable même si votre antivirus coûte un bras. Il y aura toujours un pirate qui trouvera un moyen de passer admin sous Windows même si vous avez tout mis à jour. Il y aura toujours un pirate qui arrivera à faire un saut de VLan même si vous avez le dernier switch Cisco.
Mais...
Si vous avez un antispam (même moyen), un antivirus (même moyen), un peu de sensibilisation des utilisateurs, des utilisateurs non admin de leur poste, des OS relativement à jour, de la segmentation réseau, un peu de détection pour les cas vraiment chauds et des sauvegardes bien à l'abri... le pirate qui contournera tout ça à la fois, il aura un sacré CV.

Ce principe s'appuie en partie sur celui du "maillon le plus faible" (weakest link) qui postule que le niveau de sécurité global est égal au niveau de sécurité du composant le plus faiblement protégé.

Moindre surprise (Least astonishment)

Ce principe n'est pas tout le temps considéré comme un pur principe de sécurité (il vient du monde de l'ergonomie).
Il postule d'éviter au maximum d'implémenter des comportements contre-intuitifs pour l'utilisateur afin de limiter les risques d'erreurs.

Et alors là, on a un cas d'école parfait avec AWS. Sur les permissions des stockages S3 on pouvait restreindre à AuthenticatedUsers. N'importe qui s'attend à ce que ça signifie que seuls les utilisateurs authentifiés de son entités puissent y accéder. Que néni, cela signifie que tous les utilisateurs authentifiés d'AWS en entier peuvent y accéder.
Ce comportement n'était pas intuitif car on s'attend beaucoup plus à avoir une fonction de restriction à sa propre entité qu'à tout AWS. On voit mal pourquoi on voudrait restreindre quelque chose à tous les utilisateurs d'AWS (dans ce cas autant ouvrir à tout le monde sans restriction, donc l'option Everyone suffit).
Et du coup cette erreur de configuration a été et demeure la plus fréquente sur les infrastructures cloud d'AWS. Elle a notamment occasionné des leaks considérables.

On ne doit pas ignorer les automatismes, les habitudes, les conventions, lorsque l'on conçoit une interface, au risque de faire des utilisateurs une menace pour eux-mêmes.

Privacy by design

Nous ne nous étendrons pas énormément sur ce principe, étant très en vogue, il possède déjà une littérature abondante.

Rappellons seulement ses dimensions essentielles.
Premièrement : la donnée la plus sécurisée est celle qu'on ne collecte pas.
Deuxièmement, pour ce qu'on collecte, on pseudonymise. Derrière ce barbarisme se cache en fait une très bonne pratique qui évite qu'en cas de leak le pirate fasse trop facilement joujou avec la vie numérique des utilisateurs.
Troisièmement, on garde le contrôle sur les emplacements des données sensibles. Notamment on évite qu'elles se baladent en préprod (où elles finissent par trainer sur les postes de tous les dev).

Le mot de la fin

Bien qu'ils soient bien documentés, ces principes ne sont généralement connus que des spécialistes de la sécurité informatique et très peu des développeurs et autres architectes des réseaux (alors qu'ils en sont la première cible).

Il est toujours bon de rappeler les fondamentaux et d'éviter de laisser des concepts trop peu définis (sinon le marketing s'engouffre dedans et les définitions deviennent... quantiques).

David SORIA
-
2020-09-10

Nos autres articles