Aller au contenu

CICD-SEC-8 : usage non gouverné de services tiers

CICD-SEC-8 : usage non gouverné de services tiers

Section intitulée « CICD-SEC-8 : usage non gouverné de services tiers »

Huitième entrée du Top 10 OWASP CI/CD. Libellé officiel : Ungoverned Usage of 3rd Party Services. La surface d’attaque d’une chaîne de livraison est faite des actifs propres de l’organisation et des services tiers à qui l’on a donné accès à ces actifs. Le risque tient à l’extrême facilité de cette seconde opération : quelques minutes, sans approbation.

→ Lire l’explication complète de la marmotte

Le mécanisme : cinq branchements, deux minutes chacun

Section intitulée « Le mécanisme : cinq branchements, deux minutes chacun »

Il est rare de trouver une organisation sans de nombreux tiers connectés à sa chaîne. Le référentiel prend l’exemple d’un gestionnaire de code source en service hébergé et énumère cinq méthodes de connexion : une application de la plateforme, une application OAuth, un jeton d’accès remis au tiers, une clé SSH déposée chez lui, et des événements de webhook qui lui sont envoyés.

Deux observations rendent la liste intéressante. Chacune prend entre quelques secondes et quelques minutes, et accorde des capacités allant de la lecture d’un seul dépôt à l’administration complète de l’organisation. Et malgré ce niveau de permission, aucune approbation particulière n’est le plus souvent requise : le droit d’accorder l’accès est distribué à qui a le droit de travailler.

Du côté des systèmes de construction, l’intégration est plus simple encore : une ou deux lignes dans la configuration du pipeline, ou un greffon installé depuis la place de marché de l’outil. La fonctionnalité tierce est alors importée et exécutée dans le processus de construction, avec un accès complet à ce qui est disponible à l’étape où elle tourne. Même accident que l’exécution de pipeline empoisonnée, à ceci près qu’ici l’exécution de code tiers est voulue, documentée et versionnée.

La difficulté annoncée est de gouvernance plutôt que de technique : savoir quels tiers ont accès à quels systèmes, par quelles méthodes, avec quel niveau accordé et quel niveau réellement employé. Les quatre questions sont celles de CICD-SEC-2, à ceci près que les titulaires ne sont pas des salariés et ne figurent dans aucun annuaire : d’où le Top 10 OWASP des identités non humaines et, côté contrat, la gestion des risques tiers. Les webhooks, méthode la moins surveillée des cinq, ont leurs pages propres : la sécurité des webhooks entrants et l’attaque par webhook non vérifié.

Le référentiel le formule brutalement : vu la permissivité habituelle des tiers, une organisation n’est aussi sûre que les tiers qu’elle implémente. Et comme les systèmes de la chaîne sont fortement interconnectés, la compromission d’un seul porte bien au-delà du système auquel il est branché. L’enchaînement donné est le plus instructif du texte : un tiers disposant d’un droit d’écriture sur un dépôt permet de pousser du code, ce qui déclenche une construction, laquelle exécute le code de l’attaquant sur le système de construction.

Trois incidents cités illustrent trois points d’entrée. Codecov, où la compromission d’un outil de couverture de code a servi à voler les variables d’environnement des constructions. DeepSource, où des attaquants ont compromis le compte du gestionnaire de code source d’un ingénieur de cette plateforme d’analyse, puis s’en sont servis pour obtenir les permissions de l’application DeepSource, c’est-à-dire l’accès au code de tous les clients l’ayant installée. Et Waydev, plateforme d’analyse de l’activité de développement, dont la base de données a été atteinte et les jetons OAuth de ses clients volés.

Le cas DeepSource est le plus instructif, parce qu’il décrit un privilège que les clients ne voient pas : l’application installée a ses propres permissions, indépendantes du compte qui l’a installée, et sa compromission ne se lit nulle part dans leurs journaux d’authentification. Au sens du catalogue CWE, le fond est une autorisation incorrecte : les droits accordés ne correspondent pas à la fonction. La tactique ATT&CK d’accès initial range ce chemin parmi les compromissions de chaîne d’approvisionnement, que le site traite dans les attaques sur la chaîne d’approvisionnement.

L’inventaire des tiers connectés, par méthode. Non une détection, mais la condition de toutes : applications installées, applications OAuth autorisées, jetons remis, clés SSH déposées, webhooks configurés, sur chaque système. Les cinq listes sont dans cinq écrans différents, ce qui explique largement l’absence d’inventaire.

L’écart entre permissions accordées et permissions employées. Même mesure que pour les comptes humains, plus facile ici : un tiers a un usage répétitif, donc un profil d’appels stable, et celui qui a le droit d’écrire sans jamais lire autre chose que des métadonnées se repère en un mois. Dans le même esprit, un service d’analyse qui travaille à chaque demande de fusion a une cadence prévisible, et tout usage soudain plus large est le signal qu’il faut.

Les jetons et clés sans date d’expiration. Détection triviale, correction politique : la dette de CICD-SEC-6, portée par des tiers plutôt que par des pipelines, et traitée pour Git dans les comptes de service à révoquer réellement.

Les portées OAuth plus larges que nécessaire, dont l’attaque par confusion de portée OAuth montre ce qu’un écart permet, et dont l’échange de jetons et la délégation expliquent la mécanique.

Le référentiel organise ses recommandations par cycle de vie du tiers, et ce découpage est la contribution utile de l’entrée.

À l’approbation : une vérification avant que l’accès soit accordé, où qu’il le soit dans l’écosystème d’ingénierie, et un niveau de permission aligné sur le moindre privilège. Le versant contractuel est décrit dans les clauses de sécurité d’un contrat fournisseur.

À l’intégration : une visibilité continue sur tous les tiers branchés, couvrant toutes les méthodes de chaque système, le niveau accordé et le niveau réellement employé. Le mot important est « toutes » : un inventaire qui oublie les clés SSH et les webhooks décrit la moitié de la surface.

En usage courant : chaque tiers cadré sur les seules ressources qu’il doit atteindre, retrait des permissions inutilisées, et pour ceux qui s’exécutent dans la construction, un contexte cadré à accès limité aux secrets et au code, avec des filtres de flux stricts. La logique de CICD-SEC-5 appliquée à du code dont on n’est pas l’auteur.

Au déprovisionnement : une revue périodique de tous les tiers intégrés, et le retrait de ceux qui ne servent plus. L’étape qui manque partout, pour la raison ordinaire que personne n’est fâché qu’une intégration inutile continue de fonctionner. Le geste est celui de la revue d’accès périodique, étendu aux titulaires qui ne sont pas des personnes.

La première conséquence est l’impossibilité de maintenir un contrôle d’accès par rôle dans les systèmes de la chaîne : le modèle d’autorisation défini pour les salariés ne décrit plus l’accès réel, puisqu’une partie des titulaires sont des applications que personne n’y a inscrites. « Qui peut écrire dans ce dépôt » a donc une réponse incomplète, et la partie manquante est précisément celle qui n’a pas de visage.

La seconde est le délai de réaction. Le jour où un prestataire annonce une compromission, trois questions se posent : l’avions-nous branché, sur quels dépôts, avec quelles permissions. Sans inventaire, les réponses demandent des jours, pendant lesquels le jeton reste valide. Et comme le déprovisionnement n’a jamais été fait, la liste des tiers autorisés contient des services dont l’organisation a cessé d’être cliente : le seul cas où l’on paie un risque sans payer la facture.

Pour fabriquer du logiciel, une entreprise branche sur ses outils une quantité de services extérieurs : mesure de la qualité du code, analyse automatique, suivi de l’activité de l’équipe, notifications. Chacun rend un service réel et s’installe en deux minutes.

Le problème n’est pas qu’un de ces services soit malhonnête, mais qu’on ait perdu la liste et le détail de ce qu’on leur a accordé. Il y a cinq façons de brancher un service extérieur sur un dépôt de code : installer une application, autoriser une connexion par délégation, lui remettre un jeton, lui déposer une clé, ou lui faire envoyer des notifications d’événements. Les cinq se règlent dans cinq écrans différents, ce qui suffit à expliquer pourquoi presque personne ne tient l’inventaire. Et chacune peut accorder, selon le réglage, la lecture d’un projet ou l’administration de l’ensemble.

La conséquence est arithmétique : la sécurité de l’entreprise devient celle du moins rigoureux de ses prestataires. Deux cas publics le montrent. Une plateforme d’analyse de code a vu le compte d’un de ses ingénieurs compromis ; avec ce compte, les attaquants ont obtenu les droits de l’application que cette plateforme avait installée chez ses clients, donc l’accès au code de tous, sans que rien n’apparaisse dans les journaux de connexion de ces derniers. Une autre a vu sa base de données consultée, et les autorisations d’accès de ses clients volées avec elle.

La réponse recommandée n’est pas de se passer de ces services, ce qui serait absurde, mais de les traiter comme des employés : vérification avant l’embauche, droits limités à ce qu’ils font, suivi de ce qu’ils utilisent vraiment, et surtout un départ, c’est-à-dire le retrait de l’accès quand on cesse de travailler avec eux. C’est cette dernière étape qui manque partout, parce que personne ne se plaint qu’un service inutile continue de fonctionner.

À lire aussi

Pages voisines

: les deux pages se citent l’une l’autre.