Incident response

Secret en clair dans un repo public : playbook 24 heures

Un développeur a poussé une clé AWS sur un repo public. Vous le découvrez à 22h. Plan d'action heure par heure pour limiter la casse avant le réveil de l'attaquant.

Aroua Biri

22h13, un mardi. Le CTO d'un SaaS RH m'envoie un message "on a une AWS_ACCESS_KEY_ID dans un commit poussé sur un repo public il y a 40 minutes. C'est la clé du compte prod." On a démarré le playbook qui suit. À 6h du matin, la casse était limitée à un compute spike détecté à 1h12 sur trois EC2 — révoqué avant tout dommage. La clé était scannée par au moins 4 bots d'attaquants connus dans l'heure suivant le push.

Le playbook qui suit, on l'a affiné sur 5 incidents similaires depuis 2024. Il marche pour AWS, GCP, Azure, Stripe, OpenAI, Anthropic, GitHub PAT, et la plupart des secrets cloud.

Le contexte qu'il faut intégrer en 30 secondes

Quand un secret atterrit dans un repo public sur GitHub :

  • Les bots qui scannent GitHub en continu le trouvent en 30 secondes à 5 minutes.
  • Les premiers tests d'usage frauduleux apparaissent dans les 60 minutes.
  • Le mining de crypto démarre souvent dans les 2-4 heures suivantes.
  • La fenêtre de discrétion est donc très courte. Vous ne pouvez pas attendre demain matin.

Le git push --force qui supprime le commit ne supprime pas le secret. GitHub conserve les blobs, les bots les ont déjà téléchargés. La seule action qui marche, c'est la révocation.

Heure 0 à H+1 — Révocation et confinement

H+0 à H+15 min — Révocation immédiate

Action 1, sans hésiter : révoquer le secret. Avant tout le reste.

  • AWS : IAM > Users > Security credentials > Delete access key. Pas de désactivation, suppression.
  • GCP : supprimer la service account key. Si possible désactiver la SA elle-même temporairement.
  • Stripe : Developers > API keys > Roll key.
  • GitHub PAT : Settings > Developer settings > Personal access tokens > Delete.
  • OpenAI / Anthropic : Console > API keys > Delete.

Si la clé est nécessaire au fonctionnement de prod : générer une nouvelle paire avant la révocation, mais sans dépasser 15 minutes entre génération et révocation de l'ancienne. Le compromis temps vs risque est en faveur du risque.

H+15 min à H+30 min — Audit immédiat de l'usage

Sur AWS : CloudTrail > Event history. Filtrer par la clé compromise sur les 24 dernières heures. Repérer :

  • Les RunInstances (mining ?).
  • Les CreateUser, AttachUserPolicy, CreateAccessKey (escalation et persistance).
  • Les GetObject massifs sur S3 (exfiltration).
  • Les AssumeRole inhabituels.

Sur GCP : Logs Explorer sur les 24h. Sur GitHub : Settings > Security log. Sur Stripe : Developers > Logs.

Capture d'écran de toutes les actions inhabituelles. Vous en aurez besoin pour la suite.

H+30 min à H+1h — Confinement du périmètre

Si vous voyez une seule action suspecte :

  • Couper le compte / la SA suspecte (pas seulement la clé : aussi le user).
  • Snapshot des ressources créées par l'attaquant avant de les supprimer (preuves).
  • Bloquer les IPs d'attaque au niveau du WAF / sécurité groupe si identifiables.
  • Activer le mode "high alert" sur le SIEM ou les alertes cloud.

Si rien de suspect : passer à H+1.

H+1 à H+4 — Nettoyage et investigation

H+1 à H+2 — Rotation des secrets dépendants

Une clé compromise rarement seule. Identifier tous les secrets qui partagent le même périmètre :

  • Autres clés API du même service.
  • Secrets dans le même fichier .env (souvent il y en a plusieurs).
  • Tokens dérivés (refresh tokens, session tokens).
  • Si la clé donnait accès à des credentials d'autres systèmes : faire le tour.

Rotation systématique. Documenter chaque rotation (qui, quand, quel système, ancien hash / nouveau hash).

H+2 à H+3 — Recherche d'autres secrets exposés

Le secret qui a fuité est rarement seul. C'est le moment de scanner :

  • gitleaks detect sur tous les repos publics de l'organisation.
  • trufflehog filesystem sur les workstations des dev si le secret venait d'un commit local.
  • GitGuardian Console si vous l'avez (il vous a probablement déjà alerté).
  • GitHub Advanced Security secret scanning si activé.

Un secret en public = symptôme. Faire la passe complète tant que vous êtes en mode urgence.

H+3 à H+4 — Nettoyage Git (sans s'illusionner)

Vous ne pouvez pas "supprimer" le secret de GitHub. Vous pouvez par contre :

  • Demander à GitHub Support la suppression du commit (formulaire dédié). Effectif sous 24-48h selon urgence.
  • Réécrire l'histoire avec git filter-repo ou BFG. Utile pour les futurs git clone mais inutile vis-à-vis des bots qui ont déjà copié.
  • Faire un commit propre avec le nouveau setup (sans secret).

Si le repo n'a pas besoin d'être public : le passer privé immédiatement. Beaucoup plus efficace que de nettoyer l'historique.

H+4 à H+24 — Sécurisation post-mortem

H+4 à H+8 — Hardening pour empêcher la prochaine fois

C'est le moment d'installer ce qui aurait évité l'incident :

  • Pre-commit hook côté dev : gitleaks ou trufflehog en hook installé via pre-commit.
  • Server-side hook côté GitHub : secret scanning push protection activé organisation-wide.
  • GitHub Actions qui scanne sur chaque PR.
  • Politique de gestion des secrets : Vault, Doppler, AWS Secrets Manager, GitHub Encrypted Secrets. Plus aucun secret dans un .env commité.

Ces 4 couches ne sont pas redondantes. Elles servent à des moments différents.

H+8 à H+16 — Communication interne

  • Note interne (Slack channel sécurité ou email) au CTO / DG / DPO. Factuelle, sans dramatiser.
  • Si la fuite touche des données clients : déclencher la procédure RGPD article 33 (notification CNIL dans les 72h). C'est obligatoire avant d'avoir terminé l'investigation, sur la base des informations disponibles.
  • Si la fuite touche des données régulées (santé, financier) : prévenir le DPO et le RSSI / responsable conformité.
  • Préparer un message externe si applicable (notification clients), à ne pas envoyer avant validation.

H+16 à H+24 — Préparation du post-mortem

Documenter l'incident pendant qu'il est frais :

  • Timeline détaillée (vous serez surpris de ne plus vous souvenir à J+3).
  • Cause racine (souvent : pas de pre-commit hook, ou contournement par --no-verify).
  • Actions correctives prises pendant l'incident.
  • Actions préventives à exécuter sur les 30 jours suivants.
  • Coût estimé (heures internes, ressources cloud compromises, communication, éventuelle amende).

Le post-mortem se fait à J+3 à J+7, blameless, avec tous les contributeurs au pipeline. C'est ce qui fait que ça n'arrive plus.

Les pièges qu'on voit dans la panique

Vouloir tout comprendre avant de révoquer

Tentation : "je veux d'abord savoir si ça a été exploité avant de couper, sinon je casse la prod". Mauvais arbitrage. Vous coupez d'abord, vous comprenez ensuite. Si ça casse la prod, vous régénérez en 10 minutes.

Force-push pour "nettoyer"

Vous croyez que le secret a disparu. Il est toujours là dans la base d'objets Git, accessible par hash, et déjà téléchargé par les bots. Le force-push ne sert pas à grand-chose en soi.

Ne pas notifier la CNIL parce que "on ne sait pas encore"

Le RGPD article 33 prévoit 72h, dès que vous avez connaissance de l'incident. Vous notifiez sur la base des informations disponibles, vous complétez ensuite. Ne pas notifier dans le délai = un manquement séparé, sanctionnable indépendamment de l'incident lui-même.

Cacher l'incident en interne

Tentation de protéger le dev qui a poussé. Mauvaise idée. Sans transparence interne, la cause racine ne sera pas traitée. Blameless ne veut pas dire opaque, ça veut dire qu'on ne cherche pas un coupable, on cherche un défaut de système.

Le contre-exemple instructif

Un autre cas, 2024. CTO découvre une AWS key publique à 10h du matin. Décide d'attendre la fin de la journée pour révoquer parce qu'une astreinte prod en dépendait. À 16h, 60 instances EC2 c5.24xlarge avaient été spinnées dans 4 régions pour miner du crypto. Facture AWS : 47 k€ sur la journée. Avec révocation immédiate à 10h, le coût aurait été : 0 € + 30 minutes de bricolage astreinte.

La règle qu'on enseigne : la révocation d'urgence n'est jamais "trop tôt". C'est même la seule action irréversible qui gagne du temps.

Pour la prévention systémique, voir Rotation des secrets avec Vault. Pour le cas Mercedes qui a tout déclenché en EU, voir Mercedes : fuite token GitHub.

Un sujet connexe chez vous ?

20 minutes pour cadrer ensemble. Aucune offre commerciale envoyée à froid.

Réserver un échange Calendly