Fuites de secrets : clés d'API, tokens et
credentials exposés
Une clé d'API dans un commit, un .env servi en clair, un bundle JS truffé de tokens : les secrets fuitent en continu, et des bots exploitent une clé exposée sur GitHub en quelques minutes. Comment ils fuient vraiment, ce qu'un attaquant en fait, et comment révoquer, nettoyer et détecter avant lui.
own2pwn··15 min de lecture
Un développeur pressé colle une clé AWS directement dans un script pour débloquer un déploiement du vendredi soir. Ça marche, il oublie, il commit, il push. La clé part sur un dépôt public. Personne dans l'équipe ne s'en rend compte : la CI passe au vert, la feature est en prod, tout le monde rentre chez soi. Sauf qu'à l'autre bout d'Internet, un bot qui surveille l'API de GitHub en temps réel vient de récupérer cette clé. En quelques minutes, elle sert à démarrer des instances de minage de cryptomonnaie sur votre compte cloud. La facture arrivera en fin de mois.
C'est le scénario le plus banal de la sécurité applicative moderne, et pourtant l'un des plus destructeurs. Un secret — une clé d'API, un token OAuth, un mot de passe de base de données, une clé privée SSH — n'est qu'une chaîne de caractères. Mais c'est une chaîne qui authentifie : celui qui la détient devient vous, sans avoir à casser quoi que ce soit. Il n'y a pas de faille à exploiter, pas de payload à forger. Il suffit de lire. Cet article détaille comment les secrets fuitent réellement, à quelle vitesse un attaquant les ramasse, et comment on répond quand c'est déjà arrivé — puis comment on l'empêche pour de bon.
Un secret n'est pas une vulnérabilité, c'est une clé
Un problème qui grossit, pas qui recule
On pourrait croire qu'avec la maturité des outils, la fuite de secrets appartiendrait au passé. C'est l'inverse. Chaque année, GitGuardian publie son rapport State of Secrets Sprawl, et chaque année les chiffres empirent. En 2023, ce sont 12,8 millions de nouveaux secrets qui ont été détectés sur des dépôts GitHub publics — une hausse de 28 % sur un an. L'édition suivante enfonce le clou : 23,8 millions de secrets fuités en 2024, encore +25 %, extraits de l'analyse de 1,4 milliard de commits. Le sprawl des secrets a quadruplé en quatre ans.
Le détail le plus inquiétant n'est pas le volume, c'est la persistance. GitGuardian a suivi la validité des secrets après détection : cinq jours après avoir été exposés, 91,6 % étaient encore valides. Et 70 % des secrets fuités en 2022 fonctionnaient toujours deux ans plus tard. Autrement dit, la grande majorité des credentials qui fuitent ne sont jamais révoqués. Ils restent des portes ouvertes, indéfiniment, en attendant que quelqu'un les pousse.
Cadre : cet article est défensif
Comment les secrets fuitent vraiment
Il n'existe pas une fuite de secrets, il en existe une douzaine. Le point commun : à un moment, un credential quitte le coffre où il aurait dû rester et atterrit quelque part de lisible. Voici les chemins qu'on retrouve mission après mission.
1. Le commit Git, et l'historique qui n'oublie rien
C'est la source numéro un. Un secret codé en dur, committé une fois, reste dans l'historique Git pour toujours — même si le commit suivant le supprime. Beaucoup de développeurs croient que retirer la ligne et re-committer efface le problème ; en réalité, la valeur reste accessible dans le diff du commit fautif. Un simple git log -p la ressort. Pire : un dépôt privé rendu public un jour (rachat, open-sourcing, erreur de visibilité) expose d'un coup tout son passé.
# Le secret a été "supprimé" au commit HEAD... mais il est toujours là :
git log -p -S 'AKIA' --all # cherche toute clé AWS dans TOUT l'historique
git rev-list --all | xargs git grep 'api_key' 2>/dev/null
# Un attaquant fait exactement ça, en masse, sur des milliers de dépôts.2. Le bundle JavaScript, ces clés incrustées côté front
Une croyance tenace veut qu'une variable d'environnement soit « secrète » du seul fait de s'appeler ENV. Faux : tout ce qui est injecté dans un bundle front (préfixé NEXT_PUBLIC_, VITE_, REACT_APP_…) est livré au navigateur, donc lisible par quiconque ouvre les DevTools. On retrouve régulièrement des clés Stripe, des tokens de service tiers ou des identifiants Firebase surprivilégiés directement dans le JavaScript minifié d'une SPA. Le minify ne cache rien : une recherche par motif retrouve la clé en une seconde.
3. Le fichier .env servi en clair
Un .env a sa place sur le serveur, pas dans le webroot. Pourtant, une mauvaise config de serveur, un déploiement qui copie tout le répertoire, ou un framework en mode debug, et voilà https://votresite.fr/.env qui répond un 200 OK avec l'intégralité de vos credentials. Les scanners d'opportunité testent cette URL sur le web entier, en boucle. Même famille : les .git/config exposés, les backups .env.bak, les dumps phpinfo().
4. Les buckets et le stockage cloud ouverts
Un bucket S3, un Azure Blob ou un GCP Storage mal configuré en accès public, et c'est parfois un trésor de fichiers de config, de dumps de base, de clés de service qui devient consultable par une URL devinable. La métadonnée cloud (169.254.169.254) est un autre point sensible : un endpoint vulnérable au SSRF peut servir à en extraire des credentials temporaires d'instance.
5. Les images Docker et les logs de CI
Une image Docker publiée sur un registre public embarque souvent bien plus que le binaire : un ARG de build gravé dans une couche, un .npmrc avec un token, un fichier de config oublié. Chaque couche est inspectable (docker history, dive). Côté CI/CD, un pipeline qui logue une variable en clair — un echo $TOKEN pour déboguer — et le secret se retrouve dans des logs de build parfois publics, ou accessibles à toute personne ayant un compte sur le projet.
6. Les dépôts personnels des employés
La fuite la plus difficile à voir : un développeur pousse un projet perso sur son compte GitHub personnel, avec dedans un bout de config de son employeur — une clé d'API interne, un accès à un environnement de staging. Ce dépôt n'est pas dans votre organisation, vous ne le surveillez pas, et pourtant il expose vos secrets. C'est exactement ce genre d'angle mort qui relève de la gestion du shadow IT, et qu'une surveillance externe attrape là où un audit interne ne regarde jamais.
Ce qu'un attaquant en fait, et à quelle vitesse
La vitesse est le cœur du sujet. Un secret exposé publiquement n'attend pas qu'un humain tombe dessus par hasard. Des bots automatisés surveillent l'API de GitHub en continu, filtrent le flux de commits en temps réel, et testent chaque credential découvert dans la foulée. La documentation de GitHub elle-même prévient qu'un secret committé doit être considéré comme compromis dès l'instant où il touche le dépôt.
La preuve la plus nette vient des honeytokens : des credentials leurres, sans accès réel, qu'on sème volontairement pour mesurer le temps de réaction d'un attaquant. Lorsqu'un honeytoken AWS est planté dans un dépôt public, l'alerte de première utilisation tombe souvent en quelques minutes : le temps qu'un bot lise le commit, extraie la clé et l'essaie. Ce n'est pas une course qu'on gagne à la main. Selon AWS, une part majoritaire des incidents de sécurité sur sa plateforme démarre par une clé d'accès fuitée.
Selon la nature du secret, l'abus prend des formes très différentes. Une clé cloud surprivilégiée sert au minage (le plus courant, car directement monétisable) ou à l'exfiltration de données. Un token d'API SaaS (email, SMS, paiement) sert au spam ou à la fraude. Et une fois dans la place, un attaquant cherche le vrai objectif : le mouvement latéral. Un secret ouvre rarement une porte ; il en ouvre un couloir entier.
Deux incidents qui résument tout
Les chiffres parlent, mais les cas réels marquent. Deux incidents publics, tous deux de 2022, montrent les deux visages du problème : la fuite externe qui dort des années, et le secret interne qui fait tomber toute une entreprise.
Toyota : une clé oubliée cinq ans sur GitHub
En octobre 2022, Toyota révèle une fuite de données touchant son service télématique T-Connect. La cause : un sous-traitant avait poussé, en décembre 2017, une portion du code source sur un dépôt GitHub public. Dedans, une clé d'accès en dur vers le serveur de données clients. Personne ne s'en aperçoit avant le 15 septembre 2022 — près de cinq ans plus tard. Pendant tout ce temps, la clé donnait accès aux données de 296 019 clients (adresses e-mail et numéros de gestion). Les clés du serveur ont été changées le 17 septembre. Toyota n'a pu ni confirmer ni exclure un accès malveillant durant ces cinq années.
La leçon Toyota : le périmètre déborde votre organisation
Uber : un secret en dur qui ouvre tout le SI
Septembre 2022, toujours. Un attaquant du groupe Lapsus$ obtient un accès VPN au réseau interne d'Uber par ingénierie sociale. Une fois dedans, il trouve, sur un partage réseau, des scripts PowerShell. L'un d'eux contient des identifiants admin en dur pour le système de gestion des accès à privilèges (PAM) Thycotic. Ce PAM, c'est le coffre-fort qui stocke les credentials de tout le reste. Avec cet accès admin, l'attaquant se sert : AWS, GCP, Google Drive, Slack, SentinelOne, la console HackerOne, les dépôts de code internes. Un seul secret en dur, et le SI entier bascule.
Les deux cas partagent la même racine — un credential là où il ne devrait pas être — mais tirent une conclusion complémentaire. Toyota rappelle qu'on ne peut protéger que ce qu'on voit ; Uber, qu'un secret n'est jamais isolé, il commande une chaîne d'accès. La bonne défense agit sur les deux fronts : réduire l'exposition, et cloisonner ce que chaque secret peut faire.
Répondre à une fuite : l'ordre des opérations est vital
Vous venez de découvrir un secret exposé. Le premier réflexe de beaucoup d'équipes est de foncer nettoyer l'historique Git pour « faire disparaître » la clé. C'est l'erreur classique, et elle vous met en danger. L'ordre correct est le suivant, et il n'est pas négociable.
Révoquer avant de nettoyer, toujours
La révocation est la seule action qui protège réellement : elle invalide le secret côté fournisseur, si bien que même l'attaquant qui l'a déjà copié se retrouve avec une clé morte. Tout le reste — nettoyer l'historique, purger les caches — n'est que du ménage. Tant que vous n'avez pas révoqué, la clé est vivante, et chaque minute passée à réécrire des commits est une minute où l'attaquant s'en sert. On révoque d'abord, on nettoie après.
Pourquoi le rewrite Git ne suffit jamais
Réécrire l'historique (avec git-filter-repo ou BFG) retire la valeur des commits de votre copie. Mais le secret a déjà essaimé : dans les forks et les clones qui échappent à votre réécriture, dans le cache de la plateforme, dans les vues de pull request qui gardent des références aux anciens commits, dans les archives publiques et les copies des scanners qui l'ont déjà indexé. GitHub le dit sans détour : une fois committé, un secret doit être traité comme compromis, point. Le rewrite est une opération d'hygiène — précieuse pour éviter que la clé morte ne pollue vos audits futurs — mais il ne sécurise rien. Ce qui sécurise, c'est la révocation.
# NON. Ceci ne protège rien tant que la clé n'est pas révoquée :
git filter-repo --replace-text secrets.txt # nettoie VOTRE historique...
git push --force # ...mais forks, clones, caches gardent la clé
# L'ordre qui compte :
# 1) Révoquer la clé dans la console du fournisseur (AWS/Stripe/GitHub...)
# 2) Émettre une nouvelle clé, la charger depuis un vault
# 3) Lire les logs d'accès : la clé a-t-elle été utilisée ?
# 4) SEULEMENT ENSUITE, réécrire l'historique pour l'hygiènePrévenir : sortir les secrets du code, pour de bon
La réponse à incident, c'est le rattrapage. La vraie victoire, c'est que le secret ne quitte jamais son coffre. Trois couches se complètent, du poste du développeur jusqu'à l'exécution en production.
- Le pre-commit hook — la première barrière, sur le poste du développeur. Un outil comme gitleaks ou
ggshieldscanne le diff avant le commit et bloque tout ce qui ressemble à un credential. La fuite est stoppée là où elle naît, sans jamais toucher le dépôt distant. Doublé côté serveur par la push protection de GitHub, qui refuse un push contenant un secret reconnu. - Le vault — le coffre-fort central (HashiCorp Vault, AWS Secrets Manager, un KMS). Le principe : le code ne contient jamais le secret, seulement une référence. La valeur est injectée à l'exécution, chiffrée au repos, et son accès est tracé. Un secret qui n'est jamais dans le code ne peut pas fuiter par le code.
- La rotation — l'hypothèse de départ est qu'un secret finira par fuiter. Donc on limite sa durée de vie : rotation automatique, credentials à durée courte, tokens éphémères. Un secret qui expire dans une heure vaut beaucoup moins cher pour un attaquant qu'une clé statique valide depuis trois ans.
Le moindre privilège double la mise
Détecter en continu, depuis l'extérieur
Les hooks et les vaults couvrent ce que vous maîtrisez : vos dépôts, vos pipelines. Mais les cas Toyota et des dépôts personnels d'employés le montrent, une grande partie de l'exposition vit hors de votre organisation — chez un sous-traitant, sur un compte perso, dans un bundle front livré à tous les navigateurs, dans un bucket que personne n'a inventorié. Personne à l'intérieur ne regarde là. C'est le rôle de la détection continue côté externe : adopter le point de vue de l'attaquant, partir de votre domaine racine, et remonter méthodiquement tout ce qui vous est rattaché et qui pourrait laisser fuiter un secret.
C'est exactement ce que fait notre module détection de fuites et de secrets. À partir d'un seul domaine en entrée, il découvre les dépôts Git exposés (code et historique de commits), teste les fichiers .env et configs accessibles sans authentification, inspecte les buckets cloud ouverts et les endpoints qui divulguent des secrets — le tout en continu, pas une fois par an. Détail qui compte : la valeur d'un secret trouvé est masquée avant toute écriture, pour ne pas recréer la fuite dans nos propres bases.
Cette détection s'inscrit dans une démarche plus large de découverte d'actifs exposés : on ne peut chercher des secrets que sur une surface qu'on a d'abord cartographiée. Et quand un secret ouvre la voie à une compromission plus profonde, prouver l'impact réel relève du pentest web blackbox — là où un humain enchaîne la fuite avec le reste pour montrer jusqu'où elle mène.
À retenir
- Un secret exposé n'est pas une faille à exploiter, c'est un accès direct : le coût pour l'attaquant est nul, et des bots exploitent une clé publique en quelques minutes.
- Le problème grossit : plus de 23 millions de secrets fuités sur GitHub en 2024, et 70 % des secrets de 2022 étaient encore valides deux ans après. La révocation, presque personne ne la fait.
- Les secrets fuitent par des dizaines de chemins : historique Git qui n'oublie rien, bundles JS front,
.envservis en clair, buckets ouverts, couches Docker, logs CI, dépôts perso d'employés. - En réponse : on révoque d'abord, on nettoie ensuite. Le rewrite Git ne sécurise jamais — forks, clones et caches gardent la clé. Seule la révocation coupe l'accès.
- On prévient en couches : pre-commit hooks, vaults, rotation et moindre privilège — et on détecte le reste par une surveillance externe et continue qui voit ce que l'audit interne ne regarde pas.
Vous voulez savoir quels secrets de votre organisation traînent déjà quelque part d'accessible ? C'est précisément ce que débusque notre module de détection de secrets exposés, en continu et depuis le point de vue d'un attaquant — ou parlez-en directement avec un pentester via la page contact.
Articles liés
appsec
Ransomware (rançongiciel) : anatomie d'une attaque et comment protéger sa PME
Un ransomware chiffre vos fichiers et réclame une rançon. On décortique la chaîne d'attaque, on explique pourquoi les PME sont visées, et surtout comment se protéger d'un rançongiciel avant, pendant et après.
appsec
Gestion des vulnérabilités : le guide complet (cycle de vie, priorisation CVSS + EPSS + KEV)
Un scan crache 4 000 findings, 600 en « critique ». Par où commencer ? La gestion des vulnérabilités n'est pas un scan : c'est un cycle de vie et une priorisation. On démonte le processus, et pourquoi CVSS seul ne suffit plus (EPSS, KEV, exposition).
appsec
OSINT : le renseignement en source ouverte au service de la sécurité offensive
OSINT, définition, cycle du renseignement, sources et outils (Maltego, theHarvester, Amass, Shodan, SpiderFoot, recon-ng). Comment la reconnaissance passive cartographie une surface d'attaque avant la moindre requête intrusive, et pourquoi c'est le point de départ de tout pentest.