Examiner les secrets de code

Terminée

Les applications modernes dépendent des informations d’identification pour accéder aux bases de données, AUX API, aux services cloud et à d’autres intégrations externes. Lorsque les développeurs codent en dur ces secrets directement dans le code source, ils créent une vulnérabilité de sécurité critique qui peut entraîner des violations de données, des pertes financières et des violations de conformité.

Qu’est-ce que les secrets de code ?

Les secrets de code sont des informations d’identification sensibles et des jetons d’authentification que les applications utilisent pour accéder aux ressources protégées. Contrairement aux vulnérabilités de sécurité dans la logique de code (comme l’injection SQL), les secrets sont des informations d’identification valides qui, si elles sont exposées, accordent aux attaquants un accès légitime aux systèmes et aux services.

Considérez les secrets comme les clés des services externes de votre application. Tout comme vous n’attachez pas votre clé de maison à l’extérieur de votre porte, vous ne devez pas coder en dur les informations d’identification dans les fichiers sources qui peuvent être exposés via le contrôle de version, les journaux ou les référentiels publics.

Types courants de secrets

Différentes applications nécessitent différents types de secrets en fonction de leur architecture et de leurs dépendances. Comprendre ce qui constitue un secret vous aide à les identifier dans votre codebase.

Clés API

Les clés API authentifient votre application auprès de services et de plateformes externes.

Voici quelques exemples :

  • Passerelles de paiement : clés API Stripe, secrets client PayPal, jetons d'accès Square.
  • Plateformes cloud : clés d’abonnement Azure, clés d’accès Amazon Web Services (AWS) (et clés d’accès secrètes) et clés API Google Cloud.
  • Services de communication : clés API SendGrid, jetons d’authentification Twilio, webhooks Slack.
  • Analyse et surveillance : ID de suivi Google Analytics, clés API Datadog, clés d’instrumentation Application Insights.

Voici un exemple de vulnérabilité de clé API codée en dur :

// DANGEROUS: Hard-coded Stripe API key
public class PaymentProcessor
{
    private const string StripeKey = "sk_live_51Abc123XYZ789..."; // Real secret exposed
    
    public async Task<bool> ProcessPayment(decimal amount)
    {
        StripeConfiguration.ApiKey = StripeKey;
        // Process payment...
    }
}

Si ce code est validé dans un référentiel, la clé Stripe devient visible par toute personne disposant d’un accès au référentiel. Dans les référentiels publics, la clé Stripe est immédiatement visible sur l’ensemble de l’Internet.

Chaînes de connexion de base de données

Les chaînes de connexion contiennent des informations d’identification pour accéder aux bases de données et incluent souvent plusieurs composants sensibles.

Une chaîne de connexion classique inclut :

// DANGEROUS: Hard-coded connection string with credentials
string connectionString = "Server=myserver.database.windows.net;" +
                         "Database=ProductionDB;" +
                         "User ID=admin;" +
                         "Password=MySecretP@ssw0rd123;" +
                         "Encrypt=true;";

Cette chaîne de caractères unique expose :

  • Nom d’hôte du serveur.
  • Nom de la base de données.
  • Nom d’utilisateur de l’administrateur.
  • Mot de passe de l’administrateur.

Un attaquant disposant de ces informations peut accéder directement à la base de données, contourner toute la sécurité au niveau de l’application et éventuellement extraire, modifier ou supprimer toutes les données.

Clés privées et certificats

Les clés privées pour le chiffrement, la signature et les certificats TLS ne doivent jamais apparaître dans le code source.

Voici quelques exemples :

  • Clés privées RSA pour le chiffrement.
  • Clés privées SSH pour l’accès au serveur.
  • Clés de signature JWT pour l’authentification par jeton.
  • Clés privées de certificat TLS.
// DANGEROUS: Hard-coded private key
private const string JwtPrivateKey = @"-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7...
-----END PRIVATE KEY-----";

Les clés privées dans le code source compromissent la sécurité de tout ce qu’elles protègent, ce qui permet potentiellement aux attaquants de déchiffrer des données, d’emprunter l’identité de votre application ou d’accéder à des serveurs.

Jetons OAuth et secrets client

Les informations d’identification OAuth permettent à votre application d’agir au nom des utilisateurs ou d’accéder aux API protégées.

Les types incluent :

  • ID et secrets du client OAuth.
  • Jetons d’accès personnels (PAT) pour les services tels que GitHub, GitLab.
  • Informations d’identification du principal de service pour Microsoft Entra ID.
  • Actualisez les jetons avec un accès de longue durée.
// DANGEROUS: Hard-coded OAuth credentials
public class GitHubService
{
    private const string ClientId = "Iv1.abc123def456";
    private const string ClientSecret = "1234567890abcdef1234567890abcdef12345678";
}

Ces informations d’identification peuvent permettre aux attaquants d’accéder aux données utilisateur, d’effectuer des actions en tant qu’application ou d’emprunter l’identité des utilisateurs.

Clés de chiffrement

Les clés de chiffrement symétrique utilisées pour protéger les données au repos ou en transit doivent être conservées secrètes.

// DANGEROUS: Hard-coded encryption key
private static readonly byte[] EncryptionKey = Convert.FromBase64String(
    "YourBase64EncodedKeyHere123456789ABCDEF=="
);

Si une clé de chiffrement est exposée, toutes les données chiffrées avec cette clé sont vulnérables au déchiffrement.

Pourquoi les secrets exposés sont-ils dangereux ?

Les implications en matière de sécurité des secrets exposés s’étendent bien au-delà des risques théoriques. Ils représentent des voies directes pour les attaquants afin de compromettre les systèmes, les données et les opérations.

Accès immédiat et illimité

Contrairement à l’exploitation des vulnérabilités de code qui nécessitent des compétences techniques et des conditions spécifiques, les secrets exposés fournissent un accès instantané et légitime aux ressources protégées. Un attaquant n’a pas besoin de contourner les mesures de sécurité, car il dispose d’informations d’identification valides.

Tenez compte des conséquences :

  • Informations d’identification de base de données : accès direct à la lecture, à la modification ou à la suppression de tout le contenu de la base de données.
  • Clés de service cloud : possibilité de faire tourner des ressources coûteuses, d’accéder au stockage ou de modifier des configurations.
  • Clés API de paiement : frais non autorisés, remboursements ou accès aux données de paiement du client.
  • Jetons de service de messagerie : envoi d’e-mails de courrier indésirable ou d’hameçonnage à partir de votre domaine.

Persistance et difficulté de révocation

Une fois qu’un secret est exposé, les dommages persistent jusqu’à ce que les identifiants soient rotés (modifiés). Il existe plusieurs problèmes qui compliquent la révocation :

  • Historique Git : même si vous supprimez un secret du code actuel, il reste dans l’historique de validation du référentiel.
  • Dépôts dupliqués : dans les référentiels publics, d’autres développeurs peuvent dépliquer votre code avec le secret intact.
  • Versions mises en cache ou archivées : les moteurs de recherche, les services d’archivage ou les caches internes peuvent capturer le secret exposé.
  • Fenêtre d’exposition inconnue : vous ne savez peut-être pas quand le secret a été exposé pour la première fois ou qui l’a accédé.

La seule réponse sécurisée à un secret exposé consiste à le révoquer immédiatement et à en générer un nouveau, puis à mettre à jour toutes les applications qui l’utilisent. La correction peut être perturbatrice et fastidieuse.

Conséquences réglementaires et de conformité

De nombreux frameworks réglementaires nécessitent explicitement la protection des informations d’identification et des données d’authentification sensibles :

  • Norme pci DSS (Payment Card Industry Data Security Standard) : les normes du secteur des cartes de paiement interdisent le stockage des informations d’identification d’authentification en texte clair.
  • Health Insurance Portability and Accountability Act (HIPAA) : la protection des données de santé nécessite la protection des informations d’identification d’accès.
  • Service Organization Control 2 (SOC 2) : les audits de sécurité vérifient que les informations d’identification sont correctement gérées et protégées.

Les secrets exposés peuvent entraîner des audits défaillants, des amendes réglementaires et une perte de certifications requises pour fonctionner dans certaines industries.

Scénarios réels

Comprendre comment les secrets exposés se traduisent par des violations réelles peut vous aider à apprécier l’urgence de les protéger.

Scénario 1 : Exposition du référentiel public

Un développeur valide le code dans un dépôt GitHub public avec une clé d’accès AWS codée en dur. Dans les heures suivantes :

  1. Les bots automatisés qui analysent GitHub détectent la clé.
  2. Les attaquants utilisent la clé pour faire tourner des instances EC2 coûteuses pour l’exploration de crypto-monnaie.
  3. La société reçoit une facture AWS de 50 000 $ dans les 24 heures.
  4. La clé doit être révoquée, interrompant tous les services légitimes qui utilisent cette clé.
  5. L’incident nécessite une enquête de sécurité, une réponse aux incidents et des notifications légales potentielles.

Ce scénario se produit régulièrement. La fonctionnalité de protection Push de GitHub empêche ces incidents.

Scénario 2 : Exposition des informations d’identification de base de données

Une chaîne de connexion contenant les identifiants de la base de données de production est intégrée dans un dépôt interne. Un entrepreneur disposant d’un accès au référentiel :

  1. Extrait la chaîne de connexion du code.
  2. Se connecte directement à la base de données de production.
  3. Exporte les informations personnelles des clients.
  4. La violation n’est pas détectée pendant des semaines, car l’accès apparaît légitime.

La journalisation au niveau de l’application et les contrôles de sécurité sont ignorés entièrement, car l’attaquant dispose d’informations d’identification de base de données valides.

Scénario 3 : Clé API dans l’application mobile

Une clé API est codée en dur dans une application mobile. Les chercheurs de sécurité décompilent l’application et :

  1. Extrayez la clé API du code compilé.
  2. Utilisez-le pour accéder à l’API sans limitation de débit ni suivi de l’utilisation.
  3. Énumérez toutes les données utilisateur accessibles via l’API.
  4. L’entreprise doit révoquer la clé, forçant tous les utilisateurs à mettre à jour l’application.

Le code mobile et côté client est vulnérable, car les attaquants peuvent analyser l'application compilée à leur guise.

Meilleures pratiques pour la gestion des secrets

La protection des secrets nécessite l’implémentation de modèles sécurisés tout au long du cycle de vie du développement.

Ne jamais coder en dur les secrets

Règle fondamentale : les secrets n’appartiennent pas au code source, aux fichiers de configuration suivis par contrôle de version ou au code côté client.

Au lieu de coder en dur les secrets, implémentez l’une des approches suivantes :

  • Variables d'environnement.
  • Fichiers de configuration exclus du contrôle de version.
  • Services de gestion des secrets.
  • Systèmes de configuration du runtime.

L’exemple suivant montre comment utiliser des variables d’environnement :

// SECURE: Reading secret from environment variable
public class PaymentProcessor
{
    private readonly string _stripeKey;
    
    public PaymentProcessor()
    {
        _stripeKey = Environment.GetEnvironmentVariable("STRIPE_API_KEY") 
                     ?? throw new InvalidOperationException("STRIPE_API_KEY not configured");
    }
}

Utiliser les services de gestion des secrets

Les plateformes cloud modernes fournissent des services dédiés pour le stockage et l’accès sécurisé aux secrets.

Voici quelques exemples :

  • Azure Key Vault : stockage secret centralisé avec contrôle d’accès et audit.
  • AWS Secrets Manager : rotation automatisée et stratégies d’accès affinées.
  • HashiCorp Vault : gestion des secrets d’entreprise avec des secrets dynamiques.
  • Secrets GitHub : secrets chiffrés pour les flux de travail GitHub Actions.

Ces services fournissent :

  • Chiffrement au repos et en transit.
  • Journalisation et audit d’accès.
  • Contrôles d’autorisation affinés.
  • Fonctionnalités de rotation automatique.
  • Gestion centralisée des secrets.

Faire pivoter les secrets régulièrement et immédiatement lors de leur exposition

Mettez en place des processus pour la rotation des secrets selon un calendrier et immédiatement dès que l’exposition est suspectée.

La rotation régulière limite la fenêtre d’opportunité si un secret est compromis. La rotation immédiate lorsque l’exposition est détectée réduit les dommages potentiels.

Utiliser différents secrets pour différents environnements

N’utilisez jamais les informations d’identification de production dans les environnements de développement, de test ou de préproduction.

Séparez les secrets par environnement :

  • Développement : identifiants à faible privilège, éventuellement des comptes de test.
  • Gestion intermédiaire : séparez les informations d’identification qui reflètent les autorisations de production.
  • Production : sécurité la plus élevée, accès surveillé, autorisations restreintes.

La séparation des secrets par environnement garantit que les informations d’identification de développement compromises ne peuvent pas affecter les systèmes de production.

Implémenter l’accès au privilège minimum

Configurez les secrets avec uniquement les autorisations minimales requises pour leur objectif prévu.

Par exemple:

  • Informations d’identification de base de données : accès en lecture seule si les écritures ne sont pas nécessaires.
  • Clés API : limitez les points de terminaison ou les opérations spécifiques.
  • Informations d’identification cloud : limitez les ressources et actions spécifiques.

Si un secret est exposé, des autorisations limitées réduisent les dommages potentiels.

Analyser les dépôts pour les secrets

Utilisez des outils automatisés pour détecter les secrets dans le code avant qu’ils ne soient validés ou envoyés aux référentiels.

Par exemple, GitHub fournit les outils suivants :

  • Analyse des secrets GitHub : analyse automatiquement les modèles de secrets connus.
  • Protection Push GitHub : bloque les validations qui contiennent des secrets.

Ces outils agissent comme des filets de sécurité, interceptant les secrets que les développeurs incluent accidentellement dans le code.