Cryptographic Failures
CWE-327OWASP A02:2021Aktualisiert 31. August 20266 Min. Lesezeit
Cryptographic Failures ist der Sammelbegriff für sensible Daten, die unzureichend geschützt sind, weil Kryptografie fehlt, veraltet ist oder falsch eingesetzt wird. Typische Beispiele sind mit MD5 gehashte Passwörter, Verschlüsselung im ECB-Modus und selbstgebaute Algorithmen. Die Lösung besteht aus Standardbausteinen, Argon2id für Passwörter und AES-GCM für gespeicherte Daten.
Nahezu jede Anwendung schützt irgendetwas mit Kryptografie: Passwörter in der Datenbank, ein Session-Token im Cookie, personenbezogene Daten in einem Backup. Die Algorithmen sind selten die Schwachstelle, die Art ihrer Anwendung fast immer. Im Folgenden lesen Sie, welche Fehler am häufigsten vorkommen und wodurch Sie sie ersetzen.
Was sind Cryptographic Failures?
Cryptographic Failures ist der Sammelbegriff für Schwachstellen, bei denen sensible Daten unzureichend geschützt sind, weil Kryptografie fehlt, veraltet ist oder falsch eingesetzt wird. OWASP führt die Kategorie seit 2021 als A02 in den Top 10, zuvor hieß sie Sensitive Data Exposure.
Ein Vergleich aus dem Alltag: Ein Tresor ist nur so stark wie sein schwächstes Glied, und die schwerste Tür schützt nichts, solange der Schlüssel unter der Fußmatte liegt. AES, ausgeschrieben Advanced Encryption Standard, ist nicht gebrochen; AES im falschen Modus, mit einem Schlüssel aus dem Quellcode, schützt ebenso wenig.
In der Praxis läuft die Kategorie auf eine Handvoll wiederkehrender Fehler hinaus:
- Passwörter gehasht mit MD5, SHA-1 oder blankem SHA-256. Schnelle Hashfunktionen, gebaut für Durchsatz; genau diese Geschwindigkeit macht sie für Passwörter untauglich.
- Verschlüsselung im ECB-Modus. ECB steht für Electronic Codebook: Jeder Block von sechzehn Byte läuft einzeln durch den Algorithmus, gleiche Blöcke ergeben also gleichen Geheimtext.
- Ein fest verdrahteter Initialisierungsvektor (IV). Eine IV aus dem Quellcode macht die Verschlüsselung deterministisch: Dieselbe Eingabe liefert stets dieselbe Ausgabe.
- Selbstgebaute Kryptografie. Ein XOR gegen ein festes Wort ist keine Verschlüsselung, sondern Kodierung.
- Verschlüsselung ohne Authentifizierung. Geheimtext ohne Integritätsprüfung lässt sich unbemerkt verändern.
Wie funktioniert ein Angriff auf schwache Kryptografie?
Ein Angreifer, der über SQL Injection, ein geleaktes Backup oder ein gestohlenes Administratorkonto an die Benutzertabelle kommt, hat keine Passwörter, sondern Hashes. Was danach passiert, hängt von der gewählten Hashfunktion ab.
Verwundbar:
// Speichern bei der Registrierung
$hash = md5($password);
$pdo->prepare("INSERT INTO users (email, pw_hash) VALUES (?, ?)")
->execute([$email, $hash]);
// Prüfung beim Login
if (md5($input) === $row["pw_hash"]) {
login($row);
}
Die Arbeit des Angreifers findet offline statt: Er lädt die Hashes in hashcat und probiert Milliarden Kandidaten pro Sekunde aus einer Wortliste. Bei MD5 ist dieser Rechenaufwand trivial, und gängige Passwörter stehen fertig in öffentlichen Tabellen. Ohne Salt knackt er zudem alle Konten mit demselben Passwort auf einen Schlag, während Ihre Anwendung keinen einzigen Loginversuch sieht.
Sicher:
// Argon2id: 64 MiB Arbeitsspeicher, 3 Iterationen
$options = ["memory_cost" => 65536, "time_cost" => 3, "threads" => 2];
$hash = password_hash($password, PASSWORD_ARGON2ID, $options);
// Login samt Migration alter Hashes
if (password_verify($input, $row["pw_hash"])) {
if (password_needs_rehash($row["pw_hash"], PASSWORD_ARGON2ID, $options)) {
store_hash($row["id"], password_hash($input, PASSWORD_ARGON2ID, $options));
}
login($row);
}
Argon2id ist bewusst langsam und speicherhungrig, und gerade der Speicherbedarf macht die Parallelisierung auf einer Grafikkarte unattraktiv. Der Salt wird automatisch erzeugt und im Ergebnis abgelegt, sodass gleiche Passwörter verschiedene Hashes erhalten. Ein Dump bleibt ärgerlich, doch Massenknacken fällt aus.
Das zweite Muster steckt in der Speicherung der Daten selbst.
Verwundbar:
const crypto = require("node:crypto");
// Schlüssel und IV stehen fest im Code und ändern sich nie
const KEY = Buffer.from("0123456789abcdef0123456789abcdef");
const IV = Buffer.alloc(16, 0);
// ECB verschlüsselt jeden Block einzeln, CBC nutzt immer dieselbe IV.
// Keiner der beiden Modi authentifiziert den Geheimtext.
function encrypt(plaintext, mode) {
const c = crypto.createCipheriv(mode, KEY, mode.endsWith("ecb") ? null : IV);
return Buffer.concat([c.update(plaintext, "utf8"), c.final()]);
}
Beide Varianten sind deterministisch, und darin liegt das Leck. Unter ECB bleiben gleiche Blöcke auch verschlüsselt gleich, sodass die Struktur Ihrer Daten sichtbar bleibt; die klassische Demonstration ist ein Bild, das verschlüsselt noch erkennbar ist. Bei CBC mit fester IV wird die Gleichheit ganzer Nachrichten verraten: Wer die Tabelle einsieht, erkennt, welche Datensätze denselben Wert enthalten. Ohne Authentifizierungs-Tag verändert ein Angreifer den Geheimtext zudem gezielt, und eine Anwendung, die auf falsches Padding anders reagiert, wird zum Padding Oracle, mit dem sich der gesamte Klartext rekonstruieren lässt.
Sicher:
const crypto = require("node:crypto");
const key = loadKeyFromKms(); // 32 Byte, nicht aus dem Repository
function encrypt(plaintext) {
const iv = crypto.randomBytes(12); // pro Nachricht eindeutig
const c = crypto.createCipheriv("aes-256-gcm", key, iv);
const ct = Buffer.concat([c.update(plaintext, "utf8"), c.final()]);
return Buffer.concat([iv, c.getAuthTag(), ct]);
}
function decrypt(blob) {
const d = crypto.createDecipheriv("aes-256-gcm", key, blob.subarray(0, 12));
d.setAuthTag(blob.subarray(12, 28));
// final() wirft einen Fehler, sobald ein einziges Bit verändert wurde
return Buffer.concat([d.update(blob.subarray(28)), d.final()]).toString();
}
AES-GCM, ausgeschrieben Galois/Counter Mode, verschlüsselt und authentifiziert in einem Schritt. Die Nonce ist pro Nachricht eindeutig, wird neben dem Geheimtext gespeichert und muss nicht geheim sein. Manipulation führt zu einem Fehler statt zu stillschweigend falschen Daten. Wer lieber gar keine Parameter wählt, nimmt libsodium.
Welche Auswirkungen haben Cryptographic Failures?
Technisch geht es um Daten, die Sie für verschlüsselt hielten. Geknackte Passwörter öffnen Ihre Anwendung und, weil Nutzer Passwörter wiederverwenden, deren Konten anderswo. Schlecht verschlüsselte Felder geben personenbezogene Daten oder Zahlungsdaten im Klartext preis, und wer ein verschlüsseltes Cookie verändern kann, ändert damit mitunter eine Rolle oder einen Betrag.
Geschäftlich beginnt es beim Datenleck. Dann zählt die Frage, ob die Daten für Unbefugte wirklich unlesbar waren; veraltete Kryptografie zählt dabei nicht, sodass ein Vorfall gemeldet und den Betroffenen mitgeteilt werden muss. Die Behebung ist teuer, denn jedes Passwort zurückzusetzen und jede Spalte neu zu verschlüsseln betrifft die gesamte Kette.
Deshalb reicht die Einstufung von mittel bis hoch. Ein veralteter Algorithmus auf ohnehin öffentlichen Daten ist ein sauberer Befund ohne Drama. Derselbe Fehler auf der Passworttabelle ist es nicht.
Wie erkennen Sie Cryptographic Failures?
Beginnen Sie im Code. Suchen Sie nach md5, sha1, DES, RC4 und nach ECB im Namen einer Cipher-Konfiguration sowie nach Schlüsseln oder IVs, die als literaler Wert in einer Datei stehen. Prüfen Sie auch den Generator hinter Tokens und Zurücksetzen-Links: Math.random und rand sind nicht kryptografisch sicher.
In der Datenbank ist das Format des Hashes sofort sichtbar: zweiunddreißig hexadezimale Zeichen deuten auf MD5, vierzig auf SHA-1, während bcrypt mit $2y$ und Argon2id mit $argon2id$ beginnt. Von außen verschlüsseln Sie denselben Wert zweimal und vergleichen die Ausgabe; identischer Geheimtext bedeutet ECB oder eine feste IV. Bei einem verschlüsselten Cookie kippen Sie ein Byte und beobachten, ob die Anwendung das ablehnt oder einfach weiterarbeitet.
Scanner finden die Transportseite und bekannte schwache Cipher Suites, nicht aber, dass Ihre Speicherschicht ECB verwendet oder ein Schlüssel seit Jahren derselbe ist. Statische Analyse kommt weiter, ein Code-Review noch weiter. AssistSec prüft die kryptografischen Entscheidungen Ihrer Anwendung im Rahmen eines Penetrationstests und betrachtet dabei Passwortspeicherung und Schlüsselverwaltung gemeinsam.
Wie verhindern Sie Cryptographic Failures?
- Hashen Sie Passwörter mit Argon2id. Wählen Sie bewusste Parameter für Speicher und Iterationen und weichen Sie nur auf bcrypt oder scrypt aus, wenn Argon2id fehlt. Blankes MD5, SHA-1 oder SHA-256 ist nie eine Option.
- Migrieren Sie bestehende Hashes beim Login. Prüfen Sie bei jeder erfolgreichen Anmeldung, ob das Format noch genügt, und hashen Sie neu; für ruhende Konten erzwingen Sie ein Zurücksetzen.
- Verschlüsseln Sie ausschließlich authentifiziert. Nutzen Sie AES-GCM oder XChaCha20-Poly1305, niemals ECB, mit einer frischen Nonce je Nachricht.
- Schreiben Sie keine eigene Kryptografie. Nehmen Sie libsodium oder die Standardbibliothek Ihrer Plattform; eine Eigenkonstruktion scheitert nicht sichtbar, sondern still.
- Halten Sie Schlüssel aus dem Code heraus. Legen Sie sie in einem Vault ab, nutzen Sie getrennte Schlüssel je Zweck und planen Sie die Rotation, bevor Sie sie brauchen.
- Nutzen Sie einen sicheren Generator für alles Unvorhersehbare. Session-Tokens und API-Schlüssel stammen aus
crypto.randomBytes,secretsoderSecureRandom. - Erzwingen Sie TLS und halten Sie die Konfiguration aktuell. Deaktivieren Sie alte Protokollversionen und Cipher Suites und schalten Sie HSTS ein.
Quellen
Häufige Fragen
Darf ich MD5 oder SHA-256 noch für Passwörter verwenden?
Nein. MD5, SHA-1 und SHA-256 sind darauf ausgelegt, möglichst viele Daten pro Sekunde zu verarbeiten, und auf einer modernen Grafikkarte ergibt das Milliarden Versuche pro Sekunde. Ein Passwort-Hash braucht die gegenteilige Eigenschaft, er soll langsam und speicherhungrig sein. Verwenden Sie Argon2id, ersatzweise bcrypt oder scrypt, wenn Ihre Plattform Argon2id nicht anbietet.
Was ist am ECB-Modus falsch?
ECB verschlüsselt jeden Block von sechzehn Byte unabhängig vom Rest. Gleiche Blöcke ergeben deshalb gleichen Geheimtext, sodass die Struktur Ihrer Daten sichtbar bleibt; die klassische Demonstration ist ein Bild, das nach der Verschlüsselung noch immer erkennbar ist. Zudem schützt ECB in keiner Weise vor Manipulation des Geheimtexts.
Argon2id oder bcrypt, was soll ich wählen?
Argon2id ist die erste Wahl, weil es neben Rechenzeit auch Arbeitsspeicher verlangt und damit den Vorteil spezialisierter Hardware weitgehend aufhebt. Bcrypt bleibt vertretbar, wenn Argon2id nicht verfügbar ist, sofern Sie den Kostenfaktor regelmäßig erhöhen. Was Sie in keinem Fall tun sollten, ist eine eigene Salt-und-Hash-Konstruktion zusammenzubauen.
Reicht HTTPS aus, um sensible Daten zu schützen?
Nein. TLS schützt Daten auf dem Weg zwischen Browser und Server und sagt nichts über die spätere Speicherung aus. Eine Datenbank mit MD5-Hashes oder personenbezogenen Daten im ECB-Modus ist auch auf einem Server angreifbar, der ausschließlich HTTPS spricht. Betrachten Sie Transport und Speicherung als zwei getrennte Fragen.
Ist AES-CBC unsicher?
CBC ist nicht gebrochen, aber es ist ein Modus ohne eingebaute Integritätsprüfung und mit scharfen Kanten: Eine eindeutige, nicht vorhersagbare IV pro Nachricht ist Pflicht, und der Geheimtext muss zusätzlich authentifiziert werden. In der Praxis geht das häufig schief. AES-GCM oder XChaCha20-Poly1305 erledigt Verschlüsselung und Authentifizierung in einem Schritt und ist die bessere Voreinstellung.
Verwandte Artikel
- SchwachstellenCWE-287A07:2021Broken AuthenticationBroken Authentication erklärt: wie Angreifer über Brute Force, geleakte Passwörter und vorhersagbare Session-Tokens Konten übernehmen und was dagegen hilft.
- SchwachstellenCWE-200A01:2021Information DisclosureInformation Disclosure erklärt: wie Stack Traces, .git-Verzeichnisse, Source Maps und zu großzügige API-Antworten Daten preisgeben.
- SchwachstellenCWE-319A02:2021Unsicherer Transport und schwaches TLSUnsicherer Transport erklärt: Plain HTTP, fehlendes HSTS, veraltete TLS-Versionen und Cookies ohne Secure, und wie Sie HTTPS überall erzwingen.
- SchwachstellenCWE-347A07:2021JWT-Schwachstellenalg:none, HS256/RS256-Verwechslung, ungeprüfte Signaturen und fehlende Claim-Prüfungen. Lesen Sie, wie Sie ein JWT sicher überprüfen.