Das 1MB-Passwort: Hashing-Exhaustion und Backend-Abstürze 🏎️💥

In der Welt der Cybersicherheit wird uns oft beigebracht, dass langsamer besser ist. Bei der Passwort-Hashing wählen wir bewusst Algorithmen wie Argon2id oder Bcrypt, weil sie “kostspielig” sind. Sie sind so konzipiert, dass sie CPU-Zyklen und Speicher verbrauchen, um Brute-Force-Angriffe für Hacker wirtschaftlich unmöglich zu machen.
Aber was passiert, wenn diese “Kosten” gegen dich verwendet werden?
Hier kommt der 1MB-Passwort-Angriff ins Spiel. Es ist ein stiller, eleganter und erstaunlich einfacher Denial of Service (DoS)-Vektor. Indem ein Angreifer eine übergroße Zeichenkette—sagen wir 1 Megabyte zufälliger Zeichen—in dein Login- oder Registrierungsfeld einspeist, kann er deinen Server zwingen, Sekunden oder sogar Minuten nur für eine einzelne Anfrage zu hashieren.
Ein Dutzend solcher Anfragen kann deine CPU auf 100 % bringen und so dein gesamtes Backend lahmlegen. In diesem Artikel tauchen wir in die Mechanismen der Hashing-Exhaustion ein, erklären, warum moderne Frameworks anfällig sind, und zeigen, wie man das ohne Sicherheitsverlust behebt.
1. Das Paradoxon des “langsamen” Hashings
Um diese Schwachstelle zu verstehen, müssen wir uns anschauen, wie Hashing-Funktionen funktionieren. Moderne Algorithmen wie Bcrypt, Scrypt und Argon2 sind “adaptiv”. Sie verwenden einen Work Factor (oder Kostenfaktor), um zu bestimmen, wie viele Iterationen der Hashing-Funktion ausgeführt werden.
$O(n)$ vs. Work Factor
Die meisten Entwickler konzentrieren sich auf den Work Factor. Wenn du Bcrypt auf einen Kostenfaktor von 12 setzt, dauert es ungefähr 250 ms, um ein Passwort zu hashieren. Bei 13 sind es etwa 500 ms. Diese Zeit ist konstant, egal ob das Passwort “password123” oder “correct-horse-battery-staple” ist.
Es gibt jedoch eine versteckte Variable: die Länge des Inputs ($n$).
Während der Work Factor einen exponentiellen Schutz gegen Brute-Force-Angriffe bietet, muss die Hashing-Funktion dennoch jeden einzelnen Byte des Eingabestrings verarbeiten. Die Komplexität ist ungefähr $O(n \times \text{work factor})$.
Wenn $n$ 15 Zeichen beträgt, ist der Einfluss vernachlässigbar. Bei 1.000.000 Zeichen (1MB) muss die CPU den Hash über eine riesige Datenmenge berechnen, während gleichzeitig Tausende von Iterationen laufen.
Warum das ein “stiller” Killer ist
Die meisten DoS-Angriffe sind volumetrisch (Netzwerküberflutung) oder protkollbasiert (SYN-Floods). Firewalls und Web Application Firewalls (WAFs) sind gut darin, diese zu blockieren. Aber eine POST-Anfrage mit 1MB sieht aus wie eine gültige (wenn auch große) Nutzdaten. Da sie die Anwendungsschicht angreift, umgeht sie viele traditionelle Netzwerkschutzmaßnahmen.
2. Aufbau des Angriffs: Der 1MB-Payload
Stell dir einen Standard-Login-Endpunkt vor: POST /api/v1/login.
Eine typische Anfrage könnte so aussehen:
{
"username": "victim@example.com",
"password": "pA$$w0rd123!"
}
Nun, stell dir vor, der Angreifer sendet folgendes:
{
"username": "victim@example.com",
"password": "a...[999.990 weitere 'a's]...a"
}
Der CPU-Spike
Wenn dein Server das empfängt, übergibt er die 1MB-Zeichenkette an die Hashing-Bibliothek.
- Der Speicher-Hit: Der Server muss mindestens 1MB RAM reservieren, nur um die Zeichenkette im Request-Body zu halten.
- Der Hashing-Hit: Die CPU beginnt zu arbeiten. Für Argon2id, das speicherintensiv ist, könnte es versuchen, 64MB RAM pro Hash zu reservieren und 3 Iterationen über die 1MB Eingabe laufen lassen.
- Der Thread-Block: In vielen Umgebungen (wie Node.js oder Python/Django) erfolgt das Hashing im Haupt-Thread oder einem begrenzten Worker-Pool. Während die CPU dieses 1MB-String hashiert, kann sie keine anderen Anfragen verarbeiten.
3. Vergleich der Schwachstellen: Bcrypt vs. Argon2 vs. PBKDF2
Nicht alle Hashing-Algorithmen verarbeiten lange Strings gleich. Ironischerweise bieten einige ältere “Schwachstellen” tatsächlich einen Schutzmechanismus.
Bcrypt: Der 72-Byte “Schild”
Bcrypt hat eine bekannte Eigenart: Es berücksichtigt nur die ersten 72 Bytes eines Passworts. Alle Zeichen nach dem 72. Byte werden ignoriert.
- Der Sicherheitsnachteil: Nutzer mit 100 Zeichen langen Passwörtern sind nicht so sicher, wie sie denken.
- Der DoS-Vorteil: Da es den Input fast sofort abschneidet, verursacht das Senden eines 1MB-Passworts an eine Bcrypt-Funktion normalerweise keinen CPU-Spike. Die Bibliothek schaut nur auf die ersten 72 Bytes und verwirft den Rest.
Argon2id: Die moderne Schwachstelle
Argon2id (der aktuelle Goldstandard im Jahr 2026) wurde entwickelt, um Bcrypts Einschränkungen zu beheben. Es verarbeitet beliebig lange Eingaben. Das ist großartig für Sicherheit und Passphrasen, bedeutet aber auch, dass es alle 1MB, die du sendest, treu hashieren wird. Ohne eine Anwendungsebene-Limit ist Argon2 ein primäres Ziel für Exhaustion-Angriffe.
PBKDF2: Der Iterations-Albtraum
PBKDF2 wird oft mit SHA-256 verwendet. Es hat kein 72-Byte-Limit, ist aber rein CPU-gebunden. Wenn ein Angreifer eine riesige Zeichenkette sendet, skaliert die CPU-Auslastung linear mit der Länge. In Frameworks wie Django (das standardmäßig PBKDF2 nutzt) kann das zu erheblichen Latenzen führen, auch wenn der Server nicht sofort abstürzt.
4. Warum Frameworks das oft übersehen
In 2025 und 2026 haben viele Frameworks auf “sicher standardmäßig” umgestellt, aber sie konzentrieren sich auf Mindestlänge, nicht auf Maximallänge.
- Django: Hat
MinimumLengthValidator(Standard 8 Zeichen). Es hat keinenMaximumLengthValidatorstandardmäßig für Passwörter. - Laravel: Validiert
min:8, aber seltenmax:128. - Node.js (Bcrypt/Argon2-Bibliotheken): Die meisten Bibliotheken akzeptieren einfach einen String oder Buffer. Wenn die Anwendung den rohen Request-Body an die Funktion übergibt, versucht die Bibliothek, ihn zu verarbeiten.
Die Philosophie war immer: “Warum sollten wir einen Nutzer daran hindern, ein längeres, sichereres Passwort zu verwenden?” Wir haben vergessen, dass ein 1MB “Passwort” kein Passwort ist—es ist eine Granate.
5. Strategische Gegenmaßnahmen: Schutz deines Backends
Der Schutz vor Hashing-Exhaustion erfordert einen mehrschichtigen Ansatz. Du willst die “Granate” so weit wie möglich von deiner CPU entfernen.
Gegenmaßnahme 1: Das Goldene Gesetz (Maximale Längenbegrenzung)
Der einfachste und effektivste Schutz ist, eine harte Grenze für das Passwortfeld zu setzen.
Empfehlung: Setze eine maximale Passwortlänge von 128 oder 256 Zeichen.
Selbst der extremste Sicherheitsfanatiker braucht kein Passwort länger als 256 Zeichen. Das ist lang genug für jede vernünftige Passphrase, aber kurz genug, um das Hashing auf dem Server rechenarm zu halten.
Beispiel (Django):
# settings.py
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {'min_length': 12},
},
# Optional: MaxLengthValidator hinzufügen, falls verfügbar
]
Gegenmaßnahme 2: Der SHA-256 “Pre-Hash”-Trick
Wenn du unbedingt unendliche Passwörter erlauben musst (z.B. aus kryptografischen Gründen), verwende einen Pre-Hash.
Bevor du das Passwort an Bcrypt oder Argon2 übergibst, berechne einen schnellen, nicht-adaptiven Hash wie SHA-256.
- Nutzer sendet ein 1MB-Passwort.
- Server berechnet
temp_hash = SHA-256(passwort). - Das Ergebnis von SHA-256 ist immer eine feste 32-Byte-Zeichenkette.
- Server berechnet
final_hash = Bcrypt(temp_hash).
Dadurch wird sichergestellt, dass der “kostspielige” Algorithmus (Bcrypt/Argon2) nur eine kleine, feste Eingabe verarbeitet.
Hinweis: Wenn du das implementierst, musst du konsequent sein. Du kannst für bestehende Nutzer nicht einfach auf Pre-Hashing umstellen, ohne eine Migrationsstrategie, da die Hashes sonst nicht mehr übereinstimmen.
Gegenmaßnahme 3: Ratenbegrenzung nach IP und Nutzername
Exhaustion-Angriffe basieren auf Volumen. Selbst wenn ein 1MB-Passwort 2 Sekunden zum Hashen braucht, wird eine Anfrage den Server nicht sofort killen. Zehn gleichzeitige Anfragen schon.
- Implementiere strikte Ratenbegrenzung bei Login- und Registrierungs-Endpunkten.
- Nutze einen “leaky bucket”-Algorithmus, um wiederholte Versuche von derselben IP zu verlangsamen.
Gegenmaßnahme 4: WAF und Payload-Limits
Konfiguriere deinen Load Balancer (Nginx, AWS ALB) oder WAF (Cloudflare, Akamai), um verdächtig große Payloads abzulehnen.
Wenn dein Login-Formular nur Nutzername und Passwort hat, sollte der gesamte POST-Body 10 KB nicht überschreiten. Lehnt alles größere an der Edge ab.
6. Praxisbeispiele
Node.js (Express + Joi)
Mit einer Validierungsbibliothek wie Joi kannst du diese Limits einfach durchsetzen, bevor die Daten an dein Hashing gelangen.
const loginSchema = Joi.object({
username: Joi.string().email().required(),
password: Joi.string().min(12).max(128).required() // Kritischer Punkt
});
app.post('/login', (req, res) => {
const { error } = loginSchema.validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
// Erst jetzt rufen wir den teuren Hash auf
const isValid = await bcrypt.compare(req.body.password, user.hash);
});
PHP (Laravel)
Laravel’s Validierungs-Engine macht das mit einem einzigen Befehl.
$request->validate([
'email' => 'required|email',
'password' => 'required|string|min:12|max:255', // Begrenzung setzen
]);
7. Vergleichstabelle: Hashing-Algorithmen & DoS-Schwachstellen
| Algorithmus | Standard-Maximallänge | DoS-Schwachstelle (ohne Limit) | 2026 Empfehlung |
|---|---|---|---|
| Bcrypt | 72 Bytes | Gering (durch Abschneiden) | Für Legacy / begrenzten RAM |
| Argon2id | Keine | Hoch | Beste (mit 128-Zeichen-Anwendungsbegrenzung) |
| Scrypt | Keine | Mittel bis Hoch | Gut, aber Argon2id wird bevorzugt |
| PBKDF2 | Keine | Mittel | Nur verwenden, wenn Argon2 nicht verfügbar ist |
Fazit: Verfügbarkeit ist eine Sicherheitsfunktion
Wir behandeln Sicherheit und Verfügbarkeit oft als separate Bereiche. Wir härten unsere Hashes, um Datenlecks zu verhindern (Sicherheit), vergessen aber, dass ein nicht reagierender Server ein ausgefallener Server ist (Verfügbarkeit).
Das “1MB-Passwort” erinnert daran, dass jedes Byte an Nutzereingabe Kosten verursacht. Indem du einfach eine max_length: 128-Beschränkung zu deinen Passwortfeldern hinzufügst, schließt du eine riesige DoS-Lücke, während du die höchsten Standards der Kryptografie beibehältst.
Lass nicht zu, dass deine “starke” Sicherheit dich selbst ausknockt.
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.