Un logiciel moderne n’est plus vraiment écrit, il est assemblé. Une application typique contient une poignée de lignes écrites par ses développeurs et des milliers de dépendances open source tirées automatiquement depuis Internet. Cette productivité formidable a un revers redoutable : chaque dépendance est une porte d’entrée potentielle. La sécurité de la chaîne d’approvisionnement logicielle est devenue un enjeu de premier plan.
Le risque, en clair
Quand vous installez une bibliothèque, vous installez aussi, en cascade, tout ce dont elle dépend. Un projet peut ainsi embarquer plusieurs centaines de paquets que personne dans l’équipe n’a jamais ouverts ni examinés. Il suffit qu’un seul d’entre eux, même profondément enfoui dans l’arbre des dépendances, soit compromis, abandonné ou volontairement malveillant, pour que toute l’application le soit. La confiance est transitive, et donc fragile.
Des attaques de plus en plus sophistiquées
Les attaquants l’ont bien compris, et les techniques se multiplient : paquets piégés aux noms très proches de paquets légitimes pour tromper une faute de frappe, prises de contrôle de comptes de mainteneurs fatigués ou inactifs, injection de code malveillant dans une mise à jour anodine d’une bibliothèque par ailleurs réputée. Le point commun de ces attaques : elles exploitent la confiance aveugle accordée aux dépendances.
Quatre mesures concrètes
- L’inventaire. Établir et tenir à jour la liste complète et exhaustive de ses composants logiciels. On ne peut pas protéger, ni même évaluer, ce que l’on ne connaît pas.
- L’analyse continue. Brancher un outil qui scanne automatiquement les dépendances à chaque construction et alerte dès qu’une vulnérabilité connue est publiée, sans attendre la prochaine revue manuelle.
- Le verrouillage des versions. Figer les versions exactes via des fichiers de verrouillage, pour éviter qu’une mise à jour automatique n’introduise du code non vérifié à votre insu.
- La vérification d’intégrité. S’assurer, par des sommes de contrôle ou des signatures, que le paquet téléchargé est bien celui attendu, et non une version substituée.
Le facteur humain
La technique ne fait pas tout, loin de là. Avant d’ajouter une dépendance, quelques réflexes simples réduisent considérablement le risque. Le projet est-il activement maintenu, ou abandonné depuis trois ans ? Combien de personnes y contribuent réellement ? La fonctionnalité recherchée justifie-t-elle vraiment d’ajouter des dizaines de paquets ? Parfois, écrire soi-même dix lignes de code vaut infiniment mieux qu’importer une bibliothèque entière pour une seule petite fonction.
Une responsabilité permanente
Sécuriser sa chaîne logicielle n’est pas un projet ponctuel que l’on coche une fois, mais une hygiène permanente. L’objectif n’est pas le risque zéro, qui est illusoire, mais la réduction méthodique de la surface d’attaque et la capacité à réagir vite quand une faille est annoncée. Une équipe qui peut répondre en quelques minutes à la question « sommes-nous affectés par cette vulnérabilité ? » a déjà gagné l’essentiel de la bataille.
