Unsichere Speicherung sensibler Informationen

Beschreibung

Unsichere Speicherung sensibler Informationen tritt auf, wenn Software sensible Informationen speichert, ohne den Lese- oder Schreibzugriff durch nicht autorisierte Akteure ordnungsgemäß einzuschränken. Diese Schwachstelle umfasst das Speichern sensibler Daten im Klartext, die Verwendung schwacher Verschlüsselung, das Setzen falscher Dateiberechtigungen oder das Platzieren von Daten an Orten, die für unbeabsichtigte Parteien zugänglich sind. Wenn der Lesezugriff nicht ordnungsgemäß eingeschränkt ist, können Angreifer sensible Informationen wie Anmeldedaten, persönliche Daten oder kryptographische Schlüssel stehlen. Wenn der Schreibzugriff nicht eingeschränkt ist, können Angreifer Daten ändern oder löschen, was möglicherweise zu falschem Anwendungsverhalten, Datenbeschädigung oder Denial-of-Service führt.

Risiko

Unsichere Speicherung kann zu schwerwiegenden Sicherheitsverletzungen führen. Offengelegte Anmeldedaten ermöglichen Kontoübernahme und laterale Bewegung innerhalb von Systemen. Durchgesickerte persönliche Daten führen zu Datenschutzverletzungen und regulatorischen Strafen. Kompromittierte kryptographische Schlüssel untergraben alle Sicherheitsmaßnahmen, die von diesen Schlüsseln abhängen. Modifizierte Konfigurationsdaten können das Anwendungsverhalten böswillig verändern. Diese Schwachstelle ist besonders gefährlich, weil sie über längere Zeiträume unentdeckt bleiben kann und Angreifern fortlaufenden Zugang zu sensiblen Daten ermöglicht. Das Risiko erstreckt sich über die unmittelbare Anwendung hinaus auf alle Systeme, die den kompromittierten Daten vertrauen.

Lösung

Implementieren Sie einen Defense-in-Depth-Ansatz für die Datenspeicherungssicherheit. Klassifizieren Sie Daten nach Sensibilität und wenden Sie angemessene Schutzstufen an. Verwenden Sie starke Verschlüsselung für sensible Daten im Ruhezustand mit ordnungsgemäß verwalteten Schlüsseln. Speichern Sie Verschlüsselungsschlüssel getrennt von verschlüsselten Daten, vorzugsweise in Hardware-Sicherheitsmodulen oder sicheren Schlüsselspeichern. Wenden Sie restriktive Dateiberechtigungen an (nur Eigentümer, wo möglich). Verwenden Sie plattformbereitgestellte sichere Speichermechanismen (Keychain, KeyStore). Speichern Sie niemals Anmeldedaten im Klartext oder reversibel verschlüsselt. Implementieren Sie Zugriffsprotokollierung für sensible Daten. Prüfen Sie regelmäßig Speicherberechtigungen und Verschlüsselungsstärke. Erwägen Sie Datenminimierung - speichern Sie keine sensiblen Daten, es sei denn, es ist notwendig.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Angreifer können sensible Informationen lesen, indem sie auf den unsicheren Speichermechanismus zugreifen.
IntegritätBereich: Integrität

Anwendungsdaten modifizieren - Angreifer können sensible Informationen in unsicherem Speicher überschreiben oder beschädigen.

Beispielcode

Anfälliger Code

# Anfällig: Speicherung von Anmeldedaten in Klartext-Konfigurationsdatei
import json

class VulnerableConfig:

    def save_credentials(self, username, password, api_key):
        config = {
            'username': username,
            'password': password,  # Klartext-Passwort!
            'api_key': api_key      # Klartext-API-Schlüssel!
        }

        # Anfällig: Weltweit lesbare Datei
        with open('/etc/myapp/config.json', 'w') as f:
            json.dump(config, f)
        # Standard-Berechtigungen können von anderen lesbar sein
// Anfällig: Speicherung sensibler Daten in SharedPreferences ohne Verschlüsselung
public class VulnerablePreferences {

    public void saveUserData(Context context, String password, String creditCard) {
        SharedPreferences prefs = context.getSharedPreferences(
            "user_data", Context.MODE_PRIVATE);

        // Anfällig: Im Klartext in XML gespeichert
        // /data/data/com.app/shared_prefs/user_data.xml
        prefs.edit()
            .putString("password", password)      // Klartext!
            .putString("credit_card", creditCard) // Klartext!
            .apply();

        // Root-Benutzer und Backup-Utilities können darauf zugreifen
    }
}
// Anfällig: Speicherung sensibler Daten im Browser-Speicher
class VulnerableStorage {

    saveSession(sessionToken, userEmail, paymentInfo) {
        // Anfällig: localStorage ist für jedes Skript zugänglich
        localStorage.setItem('session_token', sessionToken);
        localStorage.setItem('user_email', userEmail);
        localStorage.setItem('payment_info', JSON.stringify(paymentInfo));

        // XSS-Angriffe können all dies stehlen
    }
}
// Anfällig: Cookie speichert sensible Daten
<?php
function vulnerable_remember_me($userId, $password) {
    // Anfällig: Passwort im Cookie speichern
    setcookie('user_id', $userId, time() + 86400);
    setcookie('password', $password, time() + 86400);  // Klartext!

    // Cookie wird mit jeder Anfrage übertragen, im Browser sichtbar
}

// Anfällig: Session-Daten auf Shared Hosting
session_save_path('/tmp');  // Geteiltes Temp-Verzeichnis
session_start();
$_SESSION['credit_card'] = $creditCard;  // Andere Benutzer könnten zugreifen
?>

Korrigierter Code

# Korrigiert: Sichere Anmeldedatenspeicherung mit Verschlüsselung
import json
import os
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import base64
import keyring

class FixedConfig:

    def __init__(self, app_name: str):
        self.app_name = app_name
        self.config_dir = os.path.join(os.path.expanduser('~'), '.config', app_name)
        os.makedirs(self.config_dir, mode=0o700, exist_ok=True)

    def save_credentials(self, username: str, password: str, api_key: str):
        # Korrigiert: Passwort im OS-Keyring speichern (durch OS geschützt)
        keyring.set_password(self.app_name, 'password', password)

        # Korrigiert: API-Schlüssel im Keyring speichern
        keyring.set_password(self.app_name, 'api_key', api_key)

        # Korrigiert: Nur nicht-sensible Daten in Datei speichern
        config = {'username': username}

        config_path = os.path.join(self.config_dir, 'config.json')
        with open(config_path, 'w') as f:
            json.dump(config, f)

        # Korrigiert: Restriktive Berechtigungen
        os.chmod(config_path, 0o600)

    def get_password(self) -> str:
        return keyring.get_password(self.app_name, 'password')

    def get_api_key(self) -> str:
        return keyring.get_password(self.app_name, 'api_key')
// Korrigiert: Verwendung von EncryptedSharedPreferences und Android Keystore
import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKey;

public class FixedPreferences {

    private SharedPreferences securePrefs;

    public FixedPreferences(Context context) throws Exception {
        // Korrigiert: Master-Key im Android Keystore erstellen
        MasterKey masterKey = new MasterKey.Builder(context)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build();

        // Korrigiert: Verschlüsselte SharedPreferences verwenden
        securePrefs = EncryptedSharedPreferences.create(
            context,
            "secure_prefs",
            masterKey,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        );
    }

    public void saveUserData(String password, String creditCard) {
        // Korrigiert: Daten werden automatisch verschlüsselt
        securePrefs.edit()
            .putString("password", password)
            .putString("credit_card", creditCard)
            .apply();
    }
}
// Korrigiert: Sichere Speicherung im Browser mit Verschlüsselung
class FixedStorage {

    constructor() {
        this.cryptoKey = null;
    }

    async initialize() {
        // Verschlüsselungsschlüssel generieren oder abrufen
        this.cryptoKey = await this.getOrCreateKey();
    }

    async saveSession(sessionToken, userEmail) {
        // Korrigiert: Sensible Daten vor Speicherung verschlüsseln
        const encryptedToken = await this.encrypt(sessionToken);

        // sessionStorage für nur-Session-Daten verwenden (gelöscht beim Schließen)
        sessionStorage.setItem('session_token', JSON.stringify(encryptedToken));

        // Für weniger sensible Daten localStorage vermeiden, wenn möglich
        // HttpOnly-Cookies für Session-Tokens verwenden, wenn machbar
    }

    async encrypt(data) {
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const encoded = new TextEncoder().encode(data);

        const encrypted = await crypto.subtle.encrypt(
            { name: 'AES-GCM', iv },
            this.cryptoKey,
            encoded
        );

        return {
            iv: Array.from(iv),
            data: Array.from(new Uint8Array(encrypted))
        };
    }
}

// Besser: HttpOnly sichere Cookies für Session-Tokens verwenden
// Vom Server gesetzt: Set-Cookie: session=xyz; HttpOnly; Secure; SameSite=Strict
// Korrigiert: Sichere Session- und Cookie-Handhabung
<?php
function fixed_remember_me($userId) {
    // Korrigiert: Sicheres Zufalls-Token generieren
    $token = bin2hex(random_bytes(32));
    $tokenHash = password_hash($token, PASSWORD_DEFAULT);

    // Hash in Datenbank speichern, nicht das Token selbst
    store_remember_token($userId, $tokenHash, time() + 86400 * 30);

    // Korrigiert: HttpOnly, Secure, SameSite Cookies
    setcookie('remember_token', $token, [
        'expires' => time() + 86400 * 30,
        'path' => '/',
        'secure' => true,      // Nur HTTPS
        'httponly' => true,    // Nicht über JavaScript zugänglich
        'samesite' => 'Strict' // CSRF-Schutz
    ]);
}

// Korrigiert: Sichere Session-Konfiguration
function configure_secure_session() {
    // Privates Session-Verzeichnis verwenden
    $sessionDir = '/var/lib/myapp/sessions';
    if (!is_dir($sessionDir)) {
        mkdir($sessionDir, 0700, true);
    }
    session_save_path($sessionDir);

    // Sichere Session-Einstellungen
    ini_set('session.cookie_httponly', 1);
    ini_set('session.cookie_secure', 1);
    ini_set('session.use_strict_mode', 1);
    ini_set('session.cookie_samesite', 'Strict');

    session_start();
}
?>

CVE-Beispiele

  • CVE-2009-2272: Passwort und Benutzername im Klartext in einem Cookie gespeichert.

Verwandte CWEs

  • CWE-664: Improper Control of a Resource Through its Lifetime (Eltern)
  • CWE-312: Cleartext Storage of Sensitive Information (Kind)
  • CWE-921: Storage of Sensitive Data in a Mechanism without Access Control (Kind)
  • CWE-311: Missing Encryption of Sensitive Data (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-922: Insecure Storage of Sensitive Information." https://cwe.mitre.org/data/definitions/922.html
  2. OWASP. "Cryptographic Storage Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html
  3. OWASP. "Password Storage Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html