Untersuchen von Codegeheimnissen

Abgeschlossen

Moderne Anwendungen hängen von Anmeldeinformationen für den Zugriff auf Datenbanken, APIs, Clouddienste und andere externe Integrationen ab. Wenn Entwickler diese geheimen Schlüssel direkt im Quellcode hartcodieren, erstellen sie eine kritische Sicherheitslücke, die zu Datenschutzverletzungen, finanziellen Verlusten und Complianceverletzungen führen kann.

Was sind geheime Codeschlüssel?

Geheime Codeschlüssel sind vertrauliche Anmeldeinformationen und Authentifizierungstoken, die Von Anwendungen für den Zugriff auf geschützte Ressourcen verwendet werden. Im Gegensatz zu Sicherheitslücken in der Codelogik (wie SQL-Injection) sind Geheimnisse gültige Anmeldeinformationen, die, wenn sie offengelegt werden, Angreifern legitimen Zugriff auf Systeme und Dienste gewähren.

Stellen Sie sich geheime Schlüssel als Schlüssel für die externen Dienste Ihrer Anwendung vor. Genauso wie Sie Ihren Hausschlüssel nicht an die Außenseite Ihrer Tür anfügen würden, sollten Sie keine hartcodierten Anmeldeinformationen in Quelldateien erstellen, die über die Versionssteuerung, Protokolle oder öffentliche Repositorys verfügbar gemacht werden könnten.

Allgemeine Arten von Geheimnissen

Verschiedene Anwendungen erfordern verschiedene Arten von geheimen Schlüsseln basierend auf ihrer Architektur und Abhängigkeiten. Wenn Sie verstehen, was ein Geheimnis darstellt, können Sie sie in Ihrer Codebasis identifizieren.

API-Schlüssel

API-Schlüssel authentifizieren Ihre Anwendung bei externen Diensten und Plattformen.

Beispiele sind:

  • Zahlungsgateways: Stripe-API-Schlüssel, PayPal-Clientgeheimnisse, Square-Zugriffstoken.
  • Cloudplattformen: Azure-Abonnementschlüssel, Amazon Web Services (AWS) Zugriffstasten (und geheime Zugriffstasten) und Google Cloud API-Schlüssel.
  • Kommunikationsdienste: SendGrid-API-Schlüssel, Twilio-Authentifizierungstoken, Slack-Webhooks.
  • Analyse und Überwachung: Google Analytics-Tracking-IDs, Datadog-API-Schlüssel, Application Insights-Instrumentierungsschlüssel.

Hier ist ein Beispiel für eine hartcodierte API-Schlüssellücke:

// 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...
    }
}

Wenn dieser Code in ein Repository eingecheckt wird, wird der Stripe-Schlüssel für alle Personen mit Repository-Zugang sichtbar. In öffentlichen Repositorys ist der Stripe-Schlüssel sofort für das gesamte Internet sichtbar.

Datenbank-Verbindungszeichenfolgen

Verbindungszeichenfolgen enthalten Anmeldeinformationen für den Zugriff auf Datenbanken und enthalten häufig mehrere vertrauliche Komponenten.

Eine typische Verbindungszeichenfolge enthält:

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

Diese einzelne Zeichenfolge macht Folgendes verfügbar:

  • Serverhostname.
  • Datenbankname.
  • Administratorbenutzername.
  • Administratorkennwort.

Ein Angreifer mit diesen Informationen kann direkt auf die Datenbank zugreifen, alle Sicherheit auf Anwendungsebene umgehen und potenziell alle Daten extrahieren, ändern oder löschen.

Private Schlüssel und Zertifikate

Private Schlüssel für Verschlüsselung, Signatur und TLS-Zertifikate dürfen niemals im Quellcode angezeigt werden.

Beispiele sind:

  • RSA-Privatschlüssel für Verschlüsselung.
  • Private SSH-Schlüssel für den Serverzugriff.
  • JWT-Signaturschlüssel für die Tokenauthentifizierung.
  • Private TLS-Zertifikatschlüssel.
// DANGEROUS: Hard-coded private key
private const string JwtPrivateKey = @"-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7...
-----END PRIVATE KEY-----";

Private Schlüssel im Quellcode kompromittieren die Sicherheit von allem, was sie schützen, wodurch Angreifer Daten entschlüsseln, Ihre Anwendung imitieren oder auf Server zugreifen können.

OAuth-Token und geheime Clientschlüssel

Mit OAuth-Anmeldeinformationen kann Ihre Anwendung im Auftrag von Benutzern handeln oder auf geschützte APIs zugreifen.

Zu den Typen gehören:

  • OAuth-Client-IDs und geheime Schlüssel.
  • Persönliche Zugriffstoken (PATs) für Dienste wie GitHub, GitLab.
  • Anmeldeinformationen des Dienstprinzipals für Microsoft Entra ID
  • Aktualisieren Sie Token mit langfristigem Zugriff.
// DANGEROUS: Hard-coded OAuth credentials
public class GitHubService
{
    private const string ClientId = "Iv1.abc123def456";
    private const string ClientSecret = "1234567890abcdef1234567890abcdef12345678";
}

Mit diesen Anmeldeinformationen können Angreifer auf Benutzerdaten zugreifen, Aktionen als Anwendung ausführen oder Benutzer imitieren.

Verschlüsselungsschlüssel

Symmetrische Verschlüsselungsschlüssel, die Daten im Ruhezustand oder während der Übertragung schützen, müssen geheim gehalten werden.

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

Wenn ein Verschlüsselungsschlüssel verfügbar gemacht wird, werden alle mit diesem Schlüssel verschlüsselten Daten anfällig für die Entschlüsselung.

Warum sind aufgedeckte Geheimnisse gefährlich?

Die Sicherheitsauswirkungen von offengelegten Geheimnissen reichen weit über theoretische Risiken hinaus. Sie stellen direkte Pfade für Angreifer dar, um Systeme, Daten und Vorgänge zu kompromittieren.

Sofortiger und uneingeschränkter Zugriff

Im Gegensatz zum Ausnutzen von Coderisiken, die technische Fähigkeiten und bestimmte Bedingungen erfordern, bieten offengelegte Geheimnisse sofortigen, legitimen Zugriff auf geschützte Ressourcen. Ein Angreifer muss keine Sicherheitsmaßnahmen umgehen, da er über gültige Anmeldeinformationen verfügt.

Berücksichtigen Sie die Folgen:

  • Datenbankanmeldeinformationen: Direkter Zugriff zum Lesen, Ändern oder Löschen aller Datenbankinhalte.
  • Clouddienstschlüssel: Möglichkeit, kostenintensive Ressourcen zu starten, auf Speicher zuzugreifen oder Konfigurationen zu verändern.
  • Zahlungs-API-Schlüssel: Nicht autorisierte Gebühren, Erstattungen oder Zugriff auf Kundenzahlungsdaten.
  • E-Mail-Diensttoken: Senden von Spam- oder Phishing-E-Mails aus Ihrer Domäne.

Persistenz und Schwierigkeit des Widerrufs

Sobald ein geheimer Schlüssel offengelegt wird, bleibt der Schaden bestehen, bis die Anmeldeinformationen gedreht (geändert) werden. Es gibt mehrere Probleme, die die Sperrung erschweren:

  • Git-Verlauf: Auch wenn Sie einen geheimen Schlüssel aus dem aktuellen Code entfernen, verbleibt er im Commit-Verlauf des Repositorys.
  • Geforkte Repositorys: In öffentlichen Repositorys können andere Entwickler Ihren Code mit intaktem Geheimnis forken.
  • Zwischengespeicherte oder archivierte Versionen: Suchmaschinen, Archivdienste oder interne Caches können den verfügbar gemachten geheimen Schlüssel erfassen.
  • Unbekanntes Belichtungsfenster: Möglicherweise wissen Sie nicht, wann der geheime Schlüssel zum ersten Mal verfügbar gemacht wurde oder wer darauf zugegriffen hat.

Die einzige sichere Antwort auf einen offengelegten Geheimschlüssel besteht darin, es sofort zu widerrufen und eine neue zu generieren, und dann alle Anwendungen zu aktualisieren, die es verwenden. Korrekturen können störend und zeitaufwändig sein.

Einhaltungs- und regulatorische Folgen

Viele regulatorische Frameworks erfordern explizit den Schutz von Anmeldeinformationen und vertraulichen Authentifizierungsdaten:

  • Payment Card Industry Data Security Standard (PCI DSS): Standards der Payment Card Industry verbieten das Speichern von Authentifizierungsanmeldeinformationen im klartext.
  • Health Insurance Portability and Accountability Act (HIPAA): Der Datenschutz im Gesundheitswesen erfordert den Schutz von Zugriffsanmeldeinformationen.
  • Dienstorganisationskontrolle 2 (SOC 2): Sicherheitsüberwachungen überprüfen, ob Anmeldeinformationen ordnungsgemäß verwaltet und geschützt sind.

Offengelegte Geheimnisse können zu fehlerhaften Audits, behördlichen Geldbußen und Verlust von Zertifizierungen führen, die für den Betrieb in bestimmten Branchen erforderlich sind.

Reale Szenarien

Wenn Sie wissen, wie offengelegte Geheimnisse in echte Verstöße übersetzt werden, können Sie die Dringlichkeit des Schutzes schätzen.

Szenario 1: Gefährdung öffentlicher Repositorys

Entwickler committen Code in ein öffentliches GitHub-Repository mit einem hartcodierten AWS-Zugriffsschlüssel. Innerhalb von Stunden:

  1. Automatisierte Bots, die GitHub scannen, erkennen den Schlüssel.
  2. Angreifer verwenden den Schlüssel, um teure EC2-Instanzen für den Kryptowährungs-Mining aufzurunden.
  3. Das Unternehmen erhält innerhalb von 24 Stunden eine AWS-Rechnung von 50.000 USD.
  4. Der Schlüssel muss widerrufen werden, um alle legitimen Dienste zu unterbrechen, die ihn verwenden.
  5. Für den Vorfall sind Sicherheitsuntersuchungen, Vorfallreaktionen und potenzielle rechtliche Benachrichtigungen erforderlich.

Dieses Szenario tritt regelmäßig auf. Das Pushschutzfeature von GitHub verhindert diese Vorfälle.

Szenario 2: Gefährdung von Datenbankanmeldeinformationen

Eine Verbindungszeichenfolge mit Anmeldeinformationen für die Produktionsdatenbank wird an ein internes Repository gebunden. Ein Auftragnehmer mit Repositoryzugriff:

  1. Extrahiert die Verbindungszeichenfolge aus dem Code.
  2. Stellt eine direkte Verbindung zur Produktionsdatenbank her.
  3. Exportiert persönliche Kundeninformationen.
  4. Die Verletzung wird wochenlang nicht erkannt, da der Zugriff legitim erscheint.

Protokollierung und Sicherheitskontrollen auf Anwendungsebene werden vollständig umgangen, da der Angreifer über gültige Datenbankanmeldeinformationen verfügt.

Szenario 3: API-Schlüssel in mobiler App

Ein API-Schlüssel ist in einer mobilen Anwendung hartcodiert. Sicherheitsexperten dekompilieren die App und:

  1. Extrahieren Sie den API-Schlüssel aus dem kompilierten Code.
  2. Verwenden Sie sie, um auf die API zuzugreifen, ohne die Rate zu begrenzen oder die Nutzungsnachverfolgung zu verwenden.
  3. Aufzählen aller Benutzerdaten, auf die über die API zugegriffen werden kann.
  4. Das Unternehmen muss den Schlüssel widerrufen und alle Benutzer zwingen, die App zu aktualisieren.

Mobiler und clientseitiger Code ist anfällig, da Angreifer die kompilierte Anwendung in Ihrer Freizeit analysieren können.

Bewährte Methoden zum Verwalten von Geheimnissen

Der Schutz geheimer Schlüssel erfordert die Implementierung sicherer Muster während des gesamten Entwicklungslebenszyklus.

Niemals festcodierte Geheimnisse

Die grundlegende Regel: Geheime Schlüssel gehören nicht in Quellcode, Konfigurationsdateien, die von der Versionssteuerung oder clientseitigem Code nachverfolgt werden.

Anstatt geheime Schlüssel hartcodieren zu müssen, implementieren Sie einen der folgenden Ansätze:

  • Umgebungsvariablen.
  • Konfigurationsdateien, die von der Versionssteuerung ausgeschlossen sind.
  • Geheime Verwaltungsdienste.
  • Laufzeitkonfigurationssysteme.

Im folgenden Beispiel wird die Verwendung von Umgebungsvariablen veranschaulicht:

// 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");
    }
}

Verwenden von Geheimverwaltungsdiensten

Moderne Cloudplattformen bieten dedizierte Dienste zum sicheren Speichern und Zugreifen auf geheime Schlüssel.

Beispiele sind:

  • Azure Key Vault: Zentraler geheimer Speicher mit Zugriffssteuerung und Überwachung.
  • AWS Secrets Manager: Automatisierte Rotation und granulare Zugriffsrichtlinien.
  • HashiCorp Vault: Unternehmensgeheimnissverwaltung mit dynamischen Geheimschlüsseln.
  • GitHub Secrets: Verschlüsselte Geheime Schlüssel für GitHub-Aktionen-Workflows.

Diese Dienste bieten:

  • Verschlüsselung im Ruhezustand und während der Übertragung.
  • Zugriffsprotokollierung und -überwachung.
  • Feinkörnige Berechtigungssteuerungen.
  • Automatische Drehungsfunktionen.
  • Zentrale geheime Verwaltung.

Regelmäßiges Rotieren von Geheimnissen und sofortiges Rotieren, wenn sie offengelegt wurden

Implementieren Sie Prozesse zum Rotieren von Geheimnissen nach einem Zeitplan und zum sofortigen Rotieren, wenn ein Verdacht auf Kompromittierung besteht.

Regelmäßiger Wechsel begrenzt das Zeitfenster, wenn ein Geheimnis kompromittiert wird. Sofortige Drehung, wenn die Exposition erkannt wird, minimiert potenzielle Schäden.

Verwenden unterschiedlicher geheimer Schlüssel für verschiedene Umgebungen

Verwenden Sie niemals Produktionszugangsdaten in Entwicklungs-, Test- oder Stagingumgebungen.

Trennen Sie Geheimnisse je nach Umgebung.

  • Entwicklung: Anmeldeinformationen mit niedrigeren Berechtigungen, potenziell Testkonten.
  • Staging: Separate Anmeldeinformationen, die Produktionsberechtigungen widerspiegeln.
  • Produktion: Höchste Sicherheit, überwachter Zugriff, eingeschränkte Berechtigungen.

Durch das Trennen von Geheimnissen nach der Umgebung wird sichergestellt, dass kompromittierte Entwicklungsdaten keine Auswirkungen auf Produktionssysteme haben.

Implementieren des geringsten Berechtigungszugriffs

Konfigurieren Sie geheime Schlüssel nur mit den minimalen Berechtigungen, die für den vorgesehenen Zweck erforderlich sind.

Beispiel:

  • Datenbankanmeldeinformationen: Schreibgeschützter Zugriff, wenn Schreibvorgänge nicht erforderlich sind.
  • API-Schlüssel: Einschränken auf bestimmte Endpunkte oder Vorgänge.
  • Cloudanmeldeinformationen: Beschränken Sie sich auf bestimmte Ressourcen und Aktionen.

Wenn ein Geheimschlüssel offengelegt wird, verringern eingeschränkte Berechtigungen den potenziellen Schaden.

Scannen von Repositories nach geheimen Informationen

Verwenden Sie automatisierte Tools, um Geheimnisse im Code zu erkennen, bevor sie committet oder an Repositorys gepusht werden.

Beispielsweise stellt GitHub die folgenden Tools bereit:

  • GitHub Secret Scanning: Sucht automatisch nach bekannten geheimen Mustern.
  • GitHub-Push-Schutz: Blockiert alle Commits, die Geheimnisse enthalten.

Diese Tools dienen als Sicherheitsnetze und erfassen geheime Schlüssel, die Entwickler versehentlich in Code einfügen.