4. Le périmètre de confiance
Tu comprendras les bases de la définition d'un périmètre de confiance après avoir réalisé le challenge
Objectifs
- Comprendre la notion de périmètre de confiance
- Mettre en oeuvre une politique de gestion du périmètre de confiance
Le Condor
Kevin Mitnick est l'un des plus grands pirates de tous les temps. Mr. Mitnick a inspiré toute une génération de pirates en herbe avec sa philosophie et ses nombreux piratages, tous plus impressionnants les uns que les autres.
Cet homme a pénétré le département américain de la défense, a piraté les lignes téléphoniques d'AT&T et a même été en cavale pendant deux ans, recherché par le FBI.
Il aura passé pas mal d'années de sa vie en prison, mais son influence sur le monde du piratage est non négligeable. Cet homme ne piratait pas pour le profit, ce qui le rendait dangereux. Cet homme aimait le défi et n'avait pas froid aux yeux. La liste de ses piratages est longue ...

Quoi qu'il en soit, si Kevin a réussi à pénétrer dans des infrastructures défendues, c'est qu'elles étaient faillibles. Et ce n'était d'ailleurs pas toujours la faillibilité des infrastructures qui lui permettait de rentrer, mais celle des hommes. Mitnick est l’auteur de plusieurs livres sur le sujet du piratage. Bien sûr, cet homme s'est aujourd'hui reconverti et exerce en tant qu'expert mondialement connu.
Les hommes produisent du code faillible, des spécifications faillibles qui mènent à des protocoles faillibles. En tant que futur développeur, tu dois connaître les principes de base de la sécurité informatique et comment concevoir un code sécurisé.
Créer un environnement sécurisé est une tâche compliquée, exercée par des experts en la matière. Mais chaque développeur se doit d'avoir des notions de base en sécurité informatique pour éviter le fiasco total. La première des choses à faire est de se poser avant de commencer à coder et de se demander : comment puis-je coder de manière sécurisée ? ou plutôt comment pourrais-je pirater mon propre programme ?
Une question de sécurité
Lorsque l'Internet s'appelait l'ARPAN et qu'il n’était réservé qu’à l'élite américaine (laboratoires de recherche, universités, armée, gouvernement ...), on ne considérait pas la sécurité aussi importante qu'aujourd'hui. Le périmètre de confiance était bien plus facile à déterminer et l'on avait moins d'attaquants potentiels : le matériel informatique était bien plus onéreux et, après l'avoir acheté, il fallait connaître beaucoup de détails techniques pour y accéder. Les chevronnés ayant appris les concepts de réseau informatique et de programmation informatique ont aussi appris à exploiter le manque de précision, voire l'absence totale de périmètre de confiance, et toutes les failles que cela peut provoquer.
De nos jours et grâce à ces hackers passionnés, la sécurité est devenue un concept très très important. Nombre d'exemples d'infrastructures ou de programmes non-sécurisés jalonnent l'histoire de l'informatique. Chaque faille de sécurité est due à une erreur humaine, et rien d'autre. Un ordinateur ne réfléchit pas, il fait ce qu'on lui dit. C'est d'ailleurs probablement pour cela que les armées furent les premières à utiliser les ordinateurs !
Puisqu'un ordinateur est fondamentalement idiot, il faut faire attention à ce qu'on lui fait faire car, à chaque développement, un risque est induit et le principal concerne la sécurité. Tu peux te faire voler tes données, ou mieux encore : un pirate malveillant peut se servir d'une faille chez toi pour miner du bitcoin ou te rattacher à un réseau de bots pour émettre des dénis de services distribués.
Puisque la sécurité est un aspect fondamental du développement informatique, tu vas commencer par apprendre à définir la dangerosité de ce que tu fais. Cela passe par la définition d'un périmètre de confiance. C'est-à-dire savoir à partir de quel moment tu contrôles ton code, qui peut y avoir accès et de qui tu obtiens les informations. Et surtout, sont-elles vraies ?
Distinguer l'utile du superflu

Pour définir un périmètre de confiance, on commence par distinguer l'utile du superflu. C'est-à-dire établir une liste de priorités et ne faire que ce qui est nécessaire, ne pas ajouter de fioritures inutiles qui induisent des risques inconsidérés, pour une fonctionnalité qui apporte peu de plus-value. Ajouter des fonctionnalités augmente la surface d'attaque et pose donc des risques potentiels en termes de sécurité et de disponibilité.
Ainsi, pour un simple blog, on va se poser et essayer de dissocier ce qui est dangereux de ce qui ne l'est pas :
-
A-t-on besoin d'une interface d'administration ? Et si on décrète en avoir besoin, comment y restreint-on l'accès ? Qui peut y accéder ?
-
On veut une fonctionnalité qui nous permette d'importer des données au format XML : qui a le droit d'importer et qui ne l'a pas ? Quelles données peut-on importer et lesquelles ne peut-on pas ?
-
On veut agréger un flux RSS : quelles sources peut-on considérer de confiance ?
-
On veut utiliser cette nouvelle technologie qui est géniale, je veux l'intégrer à mon projet parce que c'est cool !
Toutes ces questions sont extrêmement importantes lorsque l'on veut construire un logiciel sécurisé. Selon mes critères :
-
A t-on besoin d'une interface d'administration ? Oui, mais uniquement si on dispose de plusieurs membres. Si je suis paranoïaque, je restreins carrément l'accès à l'interface d'admin avec certaines IP. Ou alors une authentification double facteur pour être sûr d'être notifié si quelqu'un essaie d'accéder à mon interface et possède mon mot de passe. Il ne pourra pas accéder à l'interface s’il n'a pas mon numéro de téléphone.
-
A t-on besoin d'une fonction d'import XML ? Non, pas vraiment. C'est utile, mais uniquement si le site devient très gros et que l'on veut migrer les données d'un site vers le mien. On laisse tomber l'import pour le moment.
-
On veut agréger un flux RSS, quelles sources de confiance ? AUCUNE. Toutes les données venant de l'extérieur sont potentiellement dangereuses. Elles peuvent être usurpées. Donc, politique ZERO confiance pour tout ce qui provient de l'extérieur.
-
Je veux utiliser cette super technologie qui est en vogue en ce moment. Alors, je me renseigne sur les potentiels risques de sécurité induits par l'utilisation du produit. Je me rends compte que beaucoup de gens ont mal utilisé la technologie, ce qui a donné lieu à des fiascos absolus. Pire encore, les sites mettant à disposition des failles de sécurité indiquent qu'il existe un bug qui mène à une compromission totale du système dans un certain cas. Comme je n'ai pas envie que ça m'arrive, je me résigne et vais chercher une technologie plus mature et sécurisée.
En réfléchissant, j'ai déjà supprimé une fonctionnalité et demie qui pourrait potentiellement m'apporter des problèmes. J'ai aussi viré une technologie, certes sympathique, mais qui m'aurait apporté énormément plus de problèmes que ce que je prévoyais à la base. Je me concentre donc uniquement sur ce que je dois faire : un blog qui, en soi, n'a pas un besoin de sécurité énorme. Quand bien même, en remettant en cause les risques que l'on prend à ajouter du superflu, on arrive à un design et à un programme plus sécurisés car on évite de prendre des risques inconsidérés et, si ces risques sont pris un jour, ils le sont de manière réfléchie car les risques potentiels sont déjà identifiés.
Mais bon, on a beau faire tout le travail d'analyse en amont, il reste toujours et encore des failles, parce que Bob s'est réveillé du pied gauche vendredi et qu'il voulait rentrer tôt, mis sous pression par l'équipe qui veut faire vite. Bob n'a donc pas pris le temps de réfléchir et a livré un bug qui mène à une exécution de code à distance. Personne ne le voit parce que c'est vendredi. De retour au bureau le lundi matin, notre analyste sécurité a repéré qu'un attaquant avait pris le contrôle total de la machine pendant le week-end, et ce en moins de deux heures, parce que la faille était béante et simple à exploiter. Nous n'avons plus le contrôle de notre serveur, le pirate a changé les mots de passe root pour nous enquiquiner et nous narguer. Notre site est défacé et nous avons perdu en une heure plusieurs milliers d'euros, car nous mettions à disposition une plateforme payante et très sollicitée. C'est encore une chance que nous nous soyons rendus compte que nous avions été piratés ! Le pirate aurait pu profiter du fait de ne pas être vu pour pivoter sur le réseau et atteindre d'autres machines. Auquel cas, même si on corrige le bug de Bob, le pirate est toujours là quelque part et on ne sait pas où. Bob s'en prend donc plein la tronche lundi matin et quitte l'équipe aussitôt, car il estime que c'est cette dernière qui aurait dû voir son bug ... Et puis si ça se trouve, c'est Bob qui a tout cassé exprès ?
Ne jamais faire confiance à l'utilisateur
Qui est un attaquant, sinon un utilisateur ? Une personne qui attaque ton application est toujours un utilisateur de ton application. Il faut toujours partir du principe que l'utilisateur est dangereux : soit parce qu'il est malveillant - c'est un pirate qui veut exploiter les failles de sécurité de ton site -, soit il n'est pas particulièrement malveillant mais va réaliser une manipulation hasardeuse et mettre en péril la stabilité de ton site.

Donc, dès que tu reçois une donnée d'un utilisateur, tu dois ABSOLUMENT t'assurer de sa véracité, si ce n'est de sa provenance. C'est une règle de sécurité basique. Si tu veux un site sécurisé, pense comme un attaquant ou un utilisateur qui ne comprend pas bien comment fonctionne ton site. Ne fais donc jamais confiance à l'utilisateur. JAMAIS.
L'utilisateur est en-dehors de ton périmètre de confiance. C'est une donnée que tu ne peux pas maîtriser, tout comme un serveur lointain avec lequel tu t'alimentes. Il se peut que le serveur auprès duquel tu t'alimentes en données soit usurpé par un autre, voire carrément malicieux dès le départ.
Si tu croises un inconnu dans la rue et qu'il te demande de lui passer les clés de ton logis pour utiliser tes toilettes, le fais-tu ? J'ose croire que non. Il en est de même pour les utilisateurs ou les serveurs avec lesquels tu communiques. Ne prends pas leurs informations pour vraies parce qu'ils te les ont fournies et ne leur donne aucune information ou donnée qui permettrait à l'utilisateur ou au périphérique lointain d'obtenir un accès privilégié à ton site. A moins que ce serveur n’entre dans ton périmètre de confiance, que tu dois définir clairement au préalable.
Teste, teste, teste
Les pirates réussissent à casser des sécurités en testant. Ils essayent. Leurs essais leur permettent de tirer une conclusion qui les mène ou non à la découverte d'une faille de sécurité plus ou moins grave. Ainsi, pour sécuriser, tu dois faire de même : tester ton code et sa sécurité afin de t'assurer qu'il n'y a pas d'informations compromettantes mises à disposition dans certaines circonstances.
C'est difficile de tester la sécurité de son propre code, principalement parce que tu ne vois pas où tu aurais pu te planter. Pour cela, les entreprises conscientes des problématiques de sécurité font auditer leur code et leur infrastructure par des pen-testeu.rs.ses. Ces pen-testeu.rs.ses sont payé.e.s pour trouver les failles de sécurité, les exploiter sans causer de dégâts et produire un compte-rendu clair de ce qu'ils ont trouvé. Faire faire tes tests de sécurité par une personne tierce est bien plus enrichissant car la personne ne connaît ni le code, ni le contexte, et fouinera dans des endroits auxquels tu n'auras pas pensé.
Mais, afin de pouvoir quand même réaliser des tests, tu dois penser en-dehors de ton périmètre de confiance, et surtout analyser si tu l'as respecté ou outrepassé dans tes développements. Beaucoup de hackers parlent de penser en-dehors de la boîte. C'est-à-dire : si tu sors de ta zone de confort (la technologie que tu utilises, le code que tu as écrit ou la confiance en l'entreprise), tu es très souvent amené à trouver des failles de sécurité plus ou moins grandes.
Développeur étant un métier dans lequel on se remet souvent en question, celle de la sécurité n'échappe pas à la règle. Il faut toujours remettre en question ce que l'on fait si l'on ne veut pas créer de nouveaux bugs, voire pire : des failles béantes que l'on a pas vues. Cela arrive très souvent et sur des sites très importants !
Challenge
Dresser une politique de sécurité
Un programme disponible ici ouvre le port 12345 sur ton ordinateur. Une librairie dynamique (dll) et un exécutable sont présent dans une archive .zip. Décompresse l'archive dans un dossier à part et tu pourras lancer le serveur.
Ce serveur met à disposition une API pour retirer de l'argent. Lorsque tu soumets une requête POST sur l'URI /account/withdraw avec les bons paramètres de l'argent est retiré d'un compte. Tu peux aussi créer des clients et des comptes, mais lis la documentation pour savoir comment.
Cette API sort entièrement de ton périmètre de confiance. Tu ne la contrôles pas, tu n'as pas accès au code source et surtout tu sais qu'elle buggue. Donc assure-toi que lorsque tu retires une somme celle-ci est bien retirée. Vérifie que les informations qu'elle renvoie sont vraies et ne comportent pas de coquille. J'ai compté deux failles visibles, et une troisième cachée.
Teste tous les retours de l'API. Pour prouver que tu sais comment pirater l'application, il faut que tu écrives un programme qui exécute la bonne suite d'instructions pour profiter de la (des) faille de sécurité. Ce programme est appelé dans le milieu de la cybersécurité un Proof Of Concept, c'est-à-dire un programme démontrant qu'il y a bien une faille exploitable.
Voici un lien vers la documentation. Il s'agit d'un fichier XML mais tu n'auras aucun mal à le comprendre, me tromperai-je ?
Afin de savoir comment envoyer des requêtes HTTP simplement en C#, je t'invite à consulter ce sujet sur StackOverflow.
Allez, au boulot !
Critères de validation
-
Un lien vers ta solution sur GitHub
-
Ton programme montre comment exploiter au moins une faille de sécurité