Passwort in Konfigurationsdatei

Beschreibung

Passwort in Konfigurationsdatei ist eine Schwachstelle, die auftritt, wenn ein Produkt Passwörter in Konfigurationsdateien speichert, die möglicherweise für Akteure zugänglich sind, die das Passwort nicht kennen sollten. Konfigurationsdateien werden oft an vorhersagbaren Orten gespeichert, können unzureichende Zugriffskontrollen haben und werden häufig in Backups, Versionskontrollsystemen oder Deployment-Paketen eingeschlossen. Anders als fest codierte Passwörter im Quellcode können Passwörter in Konfigurationsdateien als legitimer Speichermechanismus erscheinen, aber sie erzeugen erhebliche Sicherheitsrisiken, wenn die Dateien für unbefugte Benutzer zugänglich sind, in Logs eingeschlossen werden oder durch Anwendungsschwachstellen offengelegt werden. Diese Schwäche ist besonders problematisch, wenn Passwörter im Klartext statt in verschlüsselter oder gehashter Form gespeichert werden.

Risiko

Die Speicherung von Passwörtern in Konfigurationsdateien erzeugt mehrere Angriffsvektoren. Konfigurationsdateien können aufgrund falscher Dateiberechtigungen von anderen Benutzern auf gemeinsam genutzten Systemen lesbar sein. Webanwendungen können Konfigurationsdateien durch Directory Traversal, Local File Inclusion oder fehlkonfigurierte Webserver offenlegen. Versionskontrollsysteme enthalten oft historische Versionen von Konfigurationsdateien mit Anmeldedaten. Backup-Systeme können Konfigurationsdateien an weniger geschützten Orten speichern. Log-Aggregationssysteme können Inhalte von Konfigurationsdateien erfassen. Container-Images und Deployment-Artefakte enthalten häufig Konfigurationsdateien mit eingebetteten Anmeldedaten. Das Risiko wird verstärkt, weil Konfigurationsdateien oft als nicht-sensibel betrachtet werden und zwischen Entwicklern geteilt, in Support-Bundles eingeschlossen oder versehentlich in öffentliche Repositories committet werden können.

Lösung

Vermeiden Sie die direkte Speicherung von Passwörtern in Konfigurationsdateien wann immer möglich. Verwenden Sie stattdessen Umgebungsvariablen, Secrets-Management-Systeme oder verschlüsselte Anmeldedatenspeicher. Wenn Passwörter in Konfigurationsdateien gespeichert werden müssen, verschlüsseln Sie sie mit stärker Verschlüsselung mit Schlüsseln, die separat von der Konfiguration gespeichert werden. Verwenden Sie sichere Konfigurationsmanagement-Tools, die Anmeldedaten-Verschlüsselung und Zugriffskontrolle handhaben. Setzen Sie strenge Dateiberechtigungen für Konfigurationsdateien (Modus 600 oder 640). Schließen Sie Konfigurationsdateien mit Anmeldedaten von der Versionskontrolle aus, indem Sie .gitignore oder Äquivalente verwenden. Verwenden Sie Konfigurationsvorlagen mit Platzhalterwerten für sensible Daten. Implementieren Sie Secrets-Scanning in CI/CD-Pipelines, um versehentlich committete Anmeldedaten zu erkennen. Erwägen Sie die Verwendung externer Secrets-Manager wie HashiCorp Vault, AWS Secrets Manager oder Azure Key Vault.

Häufige Auswirkungen

AuswirkungDetails
ZugriffskontrolleBereich: Zugriffskontrolle

Ein Angreifer, der Zugang zur Konfigurationsdatei erhält, könnte das gespeicherte Passwort lesen und unbefugten Zugriff auf die geschützte Ressource erlangen. Er könnte auch das Passwort ändern, um legitime Benutzer auszusperren oder dauerhaften Zugang herzustellen.

Beispielcode

Anfällige Konfiguration (Mehrere Formate)

Die folgenden Beispiele demonstrieren anfällige Passwortspeicherung in Konfigurationsdateien:

# config.ini - Anfällig: Klartext-Passwörter
[database]
host = localhost
port = 3306
username = admin
password = SuperSecretPassword123!

[api]
key = sk-live-abc123xyz456
secret = myApiSecretKey

[smtp]
username = [email protected]
password = EmailP@ssw0rd!
# application.yml - Anfällig: Offengelegte Anmeldedaten
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/myapp
    username: app_user
    password: DatabasePassword123!  # Offengelegt!

  mail:
    host: smtp.example.com
    username: [email protected]
    password: SmtpPassword456!  # Offengelegt!

aws:
  access-key-id: AKIAIOSFODNN7EXAMPLE
  secret-access-key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY  # Offengelegt!
<!-- web.xml - Anfällig: Anmeldedaten im Deployment-Deskriptor -->
<context-param>
    <param-name>db.password</param-name>
    <param-value>ProductionDbPassword!</param-value>
</context-param>
// config.json - Anfällig: Alle Secrets in JSON-Konfiguration
{
    "database": {
        "password": "DbP@ssw0rd123"
    },
    "redis": {
        "password": "RedisSecret456"
    },
    "encryption": {
        "key": "MyEncryptionKey789"
    }
}
<?php
// config.php - Anfällig: Anmeldedaten in PHP-Konfiguration
return [
    'db_password' => 'PhpDbPassword!',
    'api_key' => 'php-api-key-12345',
    'jwt_secret' => 'jwt-signing-secret-key'
];

Korrigierte Konfiguration (Mehrere Ansätze)

# application.yml - Korrigiert: Referenzen auf externe Secrets
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/myapp
    username: ${DB_USERNAME}  # Aus Umgebungsvariable
    password: ${DB_PASSWORD}  # Aus Umgebungsvariable

  mail:
    host: smtp.example.com
    username: ${SMTP_USERNAME}
    password: ${SMTP_PASSWORD}

# Oder Secrets-Manager referenzieren
secrets:
  provider: aws-secrets-manager
  database-credentials: myapp/database
  api-credentials: myapp/external-api
// SecureConfigLoader.java - Korrigiert: Sicheres Laden von Anmeldedaten
public class SecureConfigLoader {

    private final SecretsManager secretsManager;

    public DatabaseConfig loadDatabaseConfig() {
        // Nicht-sensible Konfiguration aus Datei laden
        Properties props = loadPropertiesFile("database.properties");

        // Anmeldedaten aus Secrets-Manager laden
        Secret dbSecret = secretsManager.getSecret("myapp/database");

        return DatabaseConfig.builder()
            .host(props.getProperty("db.host"))
            .port(Integer.parseInt(props.getProperty("db.port")))
            .username(dbSecret.getString("username"))
            .password(dbSecret.getString("password"))
            .build();
    }

    public String getApiKey(String serviceName) {
        // Aus Secrets-Manager abrufen, niemals aus Konfigurationsdatei
        return secretsManager.getSecret("myapp/api-keys/" + serviceName);
    }
}
# config_loader.py - Korrigiert: Verschlüsselte Anmeldedaten mit separatem Schlüssel
import os
from cryptography.fernet import Fernet

class SecureConfig:
    def __init__(self):
        # Schlüssel aus Umgebung, nicht in Konfigurationsdatei
        key = os.environ.get('CONFIG_ENCRYPTION_KEY')
        self.cipher = Fernet(key.encode())

    def get_password(self, config_file, password_key):
        with open(config_file) as f:
            config = yaml.safe_load(f)

        encrypted_password = config.get(password_key)
        if encrypted_password:
            return self.cipher.decrypt(encrypted_password.encode()).decode()
        return None

# Verwendung mit verschlüsselter Konfiguration
# config.yml enthält: db_password: "gAAAAABf..."  (verschlüsselt)
#!/bin/bash
# Korrigiert: Umgebungsvariablen oder Secrets-Manager verwenden

# Option 1: Umgebungsvariablen (sicher setzen, nicht im Skript)
export DB_PASSWORD="${DB_PASSWORD}"

# Option 2: Aus Secrets-Manager lesen
DB_PASSWORD=$(aws secretsmanager get-secret-value \
    --secret-id myapp/database \
    --query SecretString --output text | jq -r .password)

# Option 3: Aus HashiCorp Vault lesen
DB_PASSWORD=$(vault kv get -field=password secret/myapp/database)
# Dockerfile - Korrigiert: Keine Secrets in Images einbetten
# SCHLECHT: ENV DB_PASSWORD=secret123

# GUT: Secrets zur Laufzeit injiziert
# Docker Secrets oder Umgebungsinjektion verwenden
ENV DB_PASSWORD_FILE=/run/secrets/db_password

# Anwendung liest aus Datei oder Umgebung zur Laufzeit

Die Korrekturen verwenden Umgebungsvariablen, externe Secrets-Manager, verschlüsselte Anmeldedaten mit separaten Schlüsseln oder Laufzeit-Secret-Injektion anstelle von Klartext-Passwörtern in Konfigurationsdateien.


Ausgenutzt in der Praxis

Jenkins Anmeldedaten-Offenlegung (Jenkins, 2022)

CVE-2022-38665 betraf Jenkins, das populäre CI/CD-Tool, bei dem gespeicherte Passwörter in Konfigurationsdateien für Benutzer mit Lesezugriff auf Job-Konfigurationen zugänglich waren. Die Schwachstelle legte Anmeldedaten offen, die für die Verbindung mit externen Systemen verwendet wurden, und kompromittierte potenziell gesamte Deployment-Pipelines.

Laravel .env-Datei-Offenlegung (Mehrere Organisationen, Fortlaufend)

Tausende von Laravel-Anwendungen haben ihre .env-Konfigurationsdateien mit Datenbank-Passwörtern, API-Schlüsseln und Anwendungsgeheimnissen offengelegt. Fehlkonfigurierte Webserver, offengelegte Git-Repositories und Backup-Dateien haben zu weit verbreiteter Anmeldedaten-Offenlegung geführt. Sicherheitsforscher finden regelmäßig offengelegte Laravel-Anmeldedaten durch einfache Suchmaschinenanfragen.

WordPress wp-config.php Offenlegung (WordPress-Sites, Fortlaufend)

WordPress-Installationen legen häufig wp-config.php-Dateien mit Datenbank-Anmeldedaten durch fehlkonfigurierte Server, Backup-Dateien mit vorhersagbaren Namen (.bak, .old) oder Quellcode-Repository-Offenlegung offen. Angreifer nutzen diese Anmeldedaten für Datenbankzugriff, Inhaltsmanipulation und weitere Systemkompromittierung.


Tools zum Testen/Ausnutzen

  • Gitleaks — Durchsucht Git-Repositories und Dateisysteme nach offengelegten Passwörtern und Secrets in Konfigurationsdateien.

  • TruffleHog — Tiefes Anmeldedaten-Scanning-Tool, das Secrets in Konfigurationsdateien und Git-Historie erkennt.

  • detect-secrets — Yelps Tool zur Erkennung von Secrets in Konfigurationsdateien während der Entwicklung.


CVE-Beispiele

  • CVE-2022-38665 — Jenkins speicherte unverschlüsselte Passwörter in Konfigurationsdateien, die für Benutzer mit Job-Lesezugriff zugänglich waren.

  • CVE-2019-10352 — Anwendung speicherte Datenbank-Anmeldedaten in Klartext-Konfigurationsdatei, die über Web-Verzeichnis zugänglich war.

  • CVE-2021-21972 — VMware vCenter Konfigurationsdateien mit Anmeldedaten durch Datei-Upload-Schwachstelle offengelegt.


Referenzen

  1. MITRE Corporation. "CWE-260: Password in Configuration File." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/260.html

  2. OWASP Foundation. "Credential Management Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Credential_Management_Cheat_Sheet.html

  3. HashiCorp. "Vault Documentation - Secret Management." https://www.vaultproject.io/docs

  4. AWS. "AWS Secrets Manager." https://aws.amazon.com/secrets-manager/