← Alle Artikel
ArchitekturTech

Timing-Safe Vergleiche: Warum === für API-Keys nicht reicht

Borzsport Redaktion · Datenanalyse & Technologie07. März 20265 Min. Lesezeit

Das Problem

Ein normaler String-Vergleich (===) bricht ab, sobald das erste falsche Zeichen gefunden wird. Ein Vergleich mit richtigem Präfix dauert minimal länger als einer mit komplett falschem String.

Die Attacke

Versuch "a..."     → 0.50ms (sofort falsch)
Versuch "B..."     → 0.52ms (1. Zeichen stimmt!)
Versuch "Bo..."    → 0.54ms (2 Zeichen stimmen!)
...
Character für Character den ganzen Key erraten

In der Praxis: Braucht tausende Requests pro Character und Netzwerk-Jitter erschwert die Messung. Trotzdem: Es ist ein bekannter Angriffsvektor, den man verhindern muss.

Die Lösung

// Borzsport _cors.js
const provided = req.headers['x-api-key'] || '';
if (provided.length !== key.length) return false;
return crypto.timingSafeEqual(
  Buffer.from(provided),
  Buffer.from(key)
);

timingSafeEqual vergleicht immer alle Bytes, egal wie viele stimmen. Konstante Laufzeit = keine Information für den Angreifer.

Demo: Timing-Unterschied selbst testen

Schalte zwischen naivem === und timingSafeEqual um und beobachte den Unterschied:

INTERAKTIV

Timing-Attacke Demo

Beobachte den Unterschied in der Antwortzeit zwischen naivem und timing-safe Vergleich.

Secret: Borz***********(Tipp: Fang mit "Borz" an)

Kernaussagen

  • Normaler === Vergleich leakt Information über Zeitunterschiede
  • crypto.timingSafeEqual() hat konstante Laufzeit
  • Längenvergleich vorab ist OK (Key-Länge ist typischerweise bekannt)
  • Python-Äquivalent: hmac.compare_digest()