Aikido

Le Fork s'éveille : Pourquoi les réseaux invisibles de GitHub compromettent la sécurité des packages

Écrit par
Charlie Eriksen

Cher GitHub,

Alors, voilà le problème ; il y a un problème de sécurité qui est un secret de polichinelle depuis un certain temps déjà. Les gens en parlent dans les traqueurs de problèmes. Il apparaît dans les divulgations de sécurité. Il est discuté dans des fils Slack qui se terminent inévitablement par « ...mais il faudrait que GitHub expose réellement ces données. » 

Je porte cela à votre attention parce que je suis fatigué de voir cette conversation se terminer de la même manière. La communauté de la sécurité ne demande qu'une visibilité sur les données que vous possédez déjà. Sans cela, nous sommes bloqués. Les registres de paquets ne peuvent pas avertir les utilisateurs. Les outils de sécurité ne peuvent pas signaler les références suspectes. Les attaquants, quant à eux, comprennent parfaitement cet angle mort. Ils l'exploitent déjà, tout comme Shai Hulud l'a fait.

Nous approchons de la période des fêtes. Et j'aime à penser que j'ai été plutôt sage cette année. Mon seul souhait est que vous nous donniez les outils pour mieux protéger l'écosystème. J'espère que ce n'est pas trop demander !

Quel est le problème ?

Les gestionnaires de paquets comme votre propre npm, ainsi que des tiers comme Bun et PyPI, permettent aux développeurs d'installer un dépôt GitHub directement comme dépendance. Vos propres GitHub Actions reposent sur cette même primitive.

npm install github:trusted-org/trusted-package#commit-sha

bun install github:trusted-org/trusted-package#commit-sha‍

pip install git+https://github.com/trusted-org/trusted-package#commit
- uses: trusted-org/trusted-package@commit-sha

La plupart des gens regarderaient cela et penseraient : « Où est le problème de sécurité ? Je spécifie littéralement le dépôt exact. »

Effectivement. J'ai pensé la même chose.

Mais voici ce qui se passe : si ce SHA de commit existe dans un fork du dépôt, vous tirerez le code du fork. Pas le dépôt de votre URL. Le fork. Mais qu'est-ce que c'est que ça ?

Réfléchissez-y un instant. J'attends... L'URL indique trusted-org/trusted-package. Mais si un attaquant a forké ce dépôt, ajouté un commit malveillant et vous a fait référencer le SHA de ce commit, vous venez d'installer leur code. Pas le code que vous pensiez. Pas le dépôt que vous avez spécifié. Le leur.

Pourquoi cela se produit-il ?

Cela se produit à cause du « Fork Network » de GitHub.

Il y a de fortes chances que vous n'en ayez jamais entendu parler. Voici le principe : lorsque vous forkez un dépôt, vous n'obtenez pas une copie entièrement indépendante. Votre fork rejoint un réseau, partageant le stockage d'objets git sous-jacent avec l'original et tous les autres forks. C'est ainsi que GitHub gère la mise à l'échelle. Ils ne stockent pas un million de copies des mêmes commits. C'est logique.

C'est aussi pourquoi cette attaque fonctionne.

Les commandes ci-dessus atteignent finalement l'«Télécharger une archive de dépôt (tar)» point de terminaison de GitHub. La documentation indique ceci à propos du owner paramètre :

Le paramètre owner est simplement le propriétaire du dépôt, il ne garantit pas qu'il s'agit du code de ce dépôt lui-même

Il n'y a aucune garantie que le code appartienne directement au dépôt, ni d'avertissements concernant un potentiel tirage depuis un fork. Honnêtement ? Étant donné l'architecture, ce comportement est logique. Le commit existe dans le graphe partagé. GitHub le sert. Ce n'est pas faux.

Ce qui est un problème, c'est que cela crée une ambiguïté que personne d'autre ne peut percer. Vous demandez trusted-org. Vous obtenez du code d'un attaquant. GitHub a satisfait votre demande. Vous n'avez simplement pas obtenu ce que vous pensiez demander. Et aucun outil en dehors de GitHub ne peut faire la différence.

L'asymétrie 

Écoutez, nous avons sincèrement apprécié l'ajout de cette bannière d'avertissement sur GitHub.com. Voir un avertissement pour des commits comme ceux-ci ? C'est utile. Cela montre que vous savez que c'est un problème qui mérite d'être mis en évidence.

Mais voici le problème : les gestionnaires de paquets ne consultent pas votre site web. Ils appellent votre API. Et l'API ne leur donne aucune indication que quelque chose d'inhabituel se passe. Pas de drapeau, pas de métadonnées, rien de documenté. Donc npm ne peut pas avertir les utilisateurs. PyPI ne peut pas avertir les utilisateurs. Bun ne peut pas avertir les utilisateurs. L'information existe. Vous la mettez déjà en évidence sur le frontend. Mais l'écosystème ne peut pas y accéder.

Pourquoi pas ?

Il est temps de devenir strict

Vous vous souvenez de ce point de terminaison « Télécharger une archive de dépôt (tar) » dont nous avons parlé ? Actuellement, c'est le maillon faible. Mais c'est aussi l'endroit évident pour résoudre ce problème.

Voici une idée : ajoutez un strict paramètre. Lorsqu'il est défini, la requête échoue si le commit n'existe que dans un fork, et non dans le dépôt réel spécifié. Les gestionnaires de paquets s'y conforment, tous les autres conservent le comportement actuel, et rien ne casse.

Vous effectuez déjà cette vérification sur le frontend pour cette bannière d'avertissement. Donnez simplement la même capacité à l'API. Bien sûr, il serait idéal que vous puissiez exposer plus d'informations sur le réseau de forks dans votre API en général, mais cela résout au moins le problème le plus flagrant.

Joyeuses fêtes !

Je n'écris pas ceci comme une plainte. J'écris parce que nous sommes tous alignés sur le désir d'un écosystème sécurisé et fiable. Vous avez déjà reconnu le problème en affichant l'avertissement sur GitHub.com. Maintenant, cela ferait une énorme différence d'exposer ce même signal via l'API afin que l'écosystème puisse agir en conséquence.

Une petite amélioration de votre part permettrait une amélioration significative de l'ensemble de l'écosystème. N'est-ce pas le meilleur type d'amélioration ? 

Et puisque c'est la période des fêtes, je souhaite partager quelque chose que j'ai entendu en coulisses. Ces dernières semaines, j'ai parlé avec certains des acteurs majeurs de l'écosystème, et il y a une inquiétude discrète et partagée que quelque chose puisse mal tourner pendant que tout le monde essaie de prendre du temps libre pour passer du temps avec leurs proches. Résoudre ce problème ne supprimera pas ce risque, bien sûr, mais l'inquiétude est réelle et largement ressentie.

Joyeuses fêtes, GitHub. Pour une fin d'année sereine.

Partager :

https://www.aikido.dev/blog/the-fork-awakens-why-githubs-invisible-networks-break-package-security

Abonnez-vous pour les actualités sur les menaces.

Commencez dès aujourd'hui, gratuitement.

Commencer gratuitement
Sans carte bancaire

Sécurisez votre environnement dès maintenant.

Sécurisez votre code, votre cloud et votre environnement d’exécution dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Aucune carte de crédit requise | Résultats en 32 secondes.