Keine Ratenbegrenzung auf der API
CWE-770CWE-799OWASP A04:2021Aktualisiert 4. September 20265 Min. Lesezeit
Eine API ohne Ratenbegrenzung nimmt so viele Anfragen an, wie ein Angreifer senden möchte. Das ermöglicht das erschöpfende Absuchen von Daten, das automatisierte Erraten von Zugangsdaten und das Hochtreiben Ihrer Verarbeitungskosten. Eine Begrenzung je Nutzer und je Endpunkt macht aus einem trivialen Angriff einen unpraktikablen.
Eine API ist darauf ausgelegt, maschinell aufgerufen zu werden, und genau deshalb wiegt das Fehlen einer Grenze hier schwerer als bei einem Webformular. Was für einen Menschen ein Vorgang von wenigen Sekunden ist, ist für ein Skript eine Schleife, die tausendmal pro Minute läuft. Im Folgenden lesen Sie, wohin das führt und wie Sie eine Grenze setzen, die Ihren berechtigten Nutzern nicht im Weg steht.
Was ist eine Ratenbegrenzung?
Ratenbegrenzung, im Englischen Rate Limiting, ist das Begrenzen der Zahl von Anfragen, die ein Aufrufer innerhalb einer bestimmten Zeit stellen darf. Wird diese Grenze überschritten, antwortet der Server mit einem 429 Too Many Requests, statt die Anfrage auszuführen.
Das Ziel ist nicht die Abwehr von Missbrauch im Sinne schädlicher Eingaben; dafür gibt es andere Maßnahmen. Das Ziel ist, die Wirtschaftlichkeit eines Angriffs zu stören. Praktisch jeder automatisierte Angriff beruht auf Wiederholung: Tausende Passwörter durchprobieren, Hunderttausende Kennungen ablaufen, eine Liste von E-Mail-Adressen prüfen. Solange diese Wiederholung kostenlos und unbegrenzt ist, ist der Angriff einfach. Sobald jeder Versuch Zeit kostet, verschiebt sich die Rechnung.
Vergleichen Sie es mit einem Schalter, an dem jemand Fragen stellen darf. Eine Frage nach der anderen ist normale Nutzung. Zehntausend Fragen pro Stunde sind keine Nutzung mehr, sondern eine systematische Durchsuchung, und es ist angemessen, dafür eine Grenze zu setzen, auch wenn jede einzelne Frage völlig berechtigt ist.
Wie wird eine fehlende Ratenbegrenzung ausgenutzt?
Verwundbar:
// Jede Anfrage wird ausgeführt, wie viele es auch sind
app.post('/api/v1/rabattcode/pruefen', async (req, res) => {
const code = await codes.finde(req.body.code);
res.json({ gueltig: Boolean(code), wert: code?.wert ?? null });
});
Funktional ist daran nichts falsch. Ein Angreifer sieht darin jedoch ein Orakel, das ihm je Anfrage mitteilt, ob ein Code existiert, und nichts hält ihn davon ab, das systematisch abzuarbeiten:
POST /api/v1/rabattcode/pruefen {"code":"SOMMER-0001"} → ungültig
POST /api/v1/rabattcode/pruefen {"code":"SOMMER-0002"} → ungültig
...
POST /api/v1/rabattcode/pruefen {"code":"SOMMER-4471"} → gültig, 25 Euro
Bei tausend Anfragen pro Sekunde ist die gesamte Reihe binnen einer Stunde durchlaufen. Dasselbe Muster gilt für Anmeldeversuche, für das Ablaufen von Kundennummern und für die Prüfung, welche E-Mail-Adressen Ihnen bekannt sind.
Sicher:
import { RateLimiterRedis } from 'rate-limiter-flexible';
const grenze = new RateLimiterRedis({
storeClient: redis,
keyPrefix: 'code-pruefen',
points: 20, // 20 Anfragen
duration: 60, // pro Minute
blockDuration: 300, // danach 5 Minuten gesperrt
});
app.post('/api/v1/rabattcode/pruefen', async (req, res) => {
const schluessel = req.nutzer?.id ?? req.ip; // Konto vor IP-Adresse
try {
const status = await grenze.consume(schluessel);
res.set('RateLimit-Remaining', String(status.remainingPoints));
} catch (ueber) {
res.set('Retry-After', String(Math.ceil(ueber.msBeforeNext / 1000)));
return res.status(429).json({ fehler: 'Zu viele Anfragen' });
}
const code = await codes.finde(req.body.code);
res.json({ gueltig: Boolean(code), wert: code?.wert ?? null });
});
Die Begrenzung wird in einem gemeinsamen Speicher geführt, damit sie auch dann stimmt, wenn mehrere Server hinter einem Lastverteiler laufen; eine Begrenzung im Arbeitsspeicher eines einzelnen Prozesses lässt sich mit wenigen Anfragen umgehen. Der Schlüssel ist bevorzugt das Konto, da ein Angreifer dieses nicht einfach wechseln kann, mit der IP-Adresse als Rückfall für anonyme Anfragen. Der Retry-After-Header teilt berechtigten Clients höflich mit, wann sie es erneut versuchen dürfen.
X-Forwarded-For, und den kann ein Angreifer selbst mitsenden. Vertrauen Sie diesem Wert, ohne zu prüfen, welcher Proxy ihn gesetzt hat, umgeht er Ihre Begrenzung, indem er bei jeder Anfrage eine andere Adresse angibt.Welche Auswirkungen hat eine fehlende Ratenbegrenzung?
Der Schweregrad wird üblicherweise als mittel bewertet, da das Fehlen einer Begrenzung für sich genommen selten zu einer Kompromittierung führt. Die Bedeutung liegt in den Angriffen, die dadurch machbar werden.
Die erste Kategorie ist das erschöpfende Absuchen von Daten. Besteht ein Endpunkt, der anhand einer Kennung etwas zurückgibt, kann ein Angreifer ohne Begrenzung die gesamte Reihe ablaufen und eine Datenbank nach außen kopieren, Anfrage für Anfrage, sämtlich ordnungsgemäß autorisiert. In Verbindung mit zu weit gefasster Autorisierung auf Objektebene ist das eine der häufigsten Ursachen großflächiger Datenlecks bei APIs.
Die zweite ist das Erraten von Geheimnissen: Passwörter, Einmalcodes, Wiederherstellungstoken und Rabattcodes. Ein sechsstelliger Zwei-Faktor-Code kennt eine Million Möglichkeiten, was ohne Begrenzung in Reichweite liegt und mit einer Grenze von fünf Versuchen völlig unerreichbar ist.
Die dritte ist weniger bekannt, in der Praxis aber kostspielig: das Hochtreiben Ihrer Verarbeitungskosten. Endpunkte, die eine aufwendige Suche ausführen, ein PDF erzeugen, eine E-Mail oder SMS versenden oder einen kostenpflichtigen Dienst Dritter aufrufen, kosten je Aufruf Geld. Ohne Begrenzung kann ein Angreifer diese Rechnung in die Höhe treiben oder Ihren Dienst schlicht überlasten.
Wie spürt man eine fehlende Ratenbegrenzung auf?
Ein Tester sendet in hohem Tempo eine Reihe von Anfragen an die empfindlichsten Endpunkte, also Anmelden, Passwortwiederherstellung, Suchfunktionen und Endpunkte, die anhand einer Kennung abfragen, und schaut, ob ein Punkt kommt, an dem der Server abzuweisen beginnt. Läuft alles weiter, fehlt die Begrenzung.
Danach wird versucht, die Begrenzung zu umgehen, denn sie ist häufiger vorhanden als wirksam. Klassische Umwege sind das Wechseln der IP-Adresse über einen Header wie X-Forwarded-For, das Variieren von Groß- und Kleinschreibung oder abschließenden Schrägstrichen im Pfad, der Wechsel zwischen verschiedenen API-Versionen, die zu derselben Funktion führen, und das Verteilen von Anfragen auf mehrere Konten. Ebenso wird geprüft, ob die Begrenzung in einem gemeinsamen Speicher geführt wird oder je Server und ob sie auch auf der API gilt und nicht nur in der Weboberfläche. AssistSec prüft zusätzlich, ob die Abweisung selbst nichts preisgibt: Eine Begrenzung, die nur bei bestehenden Konten greift, verrät genau, welche Konten existieren.
Wie verhindert man eine fehlende Ratenbegrenzung?
- Setzen Sie eine Begrenzung je Endpunkt, abgestimmt auf dessen Kosten und Empfindlichkeit.
- Stützen Sie die Begrenzung auf das Konto, wo es möglich ist, und auf die IP-Adresse bei anonymen Anfragen.
- Führen Sie die Zähler in einem gemeinsamen Speicher, damit die Begrenzung über mehrere Server hinweg stimmt.
- Antworten Sie mit
429und einemRetry-After-Header, damit berechtigte Clients sich anpassen können. - Wenden Sie strengere Grenzen auf Anmeldung, Passwortwiederherstellung, Verifizierungscodes und aufwendige Suchen an.
- Bestimmen Sie die IP-Adresse nur aus Headern, die Ihr eigener vertrauenswürdiger Proxy gesetzt hat.
- Führen Sie die Begrenzung zunächst im Warnmodus ein, messen Sie die tatsächliche Nutzung und setzen Sie danach durch.
- Begrenzen Sie auch den Umfang von Antworten durch Seitenaufteilung und eine Höchstzahl an Ergebnissen je Anfrage.
- Überwachen und alarmieren Sie bei Mustern, die auf systematisches Absuchen hindeuten, auch wenn die Grenze nicht erreicht wird.
Quellen
Häufige Fragen
Worauf sollte die Begrenzung beruhen?
Auf der verlässlichsten Kennung, die Sie haben. Bei angemeldeten Nutzern ist das das Konto, denn das kann ein Angreifer nicht einfach wechseln. Bei anonymen Anfragen ist die IP-Adresse der einzige Anhaltspunkt, mit der Einschränkung, dass Nutzer hinter einem Büronetz diese Adresse teilen. Kombinieren Sie beides, wo es geht.
Genügt eine einzige globale Begrenzung nicht?
Nein, denn Endpunkte unterscheiden sich stark in Kosten und Empfindlichkeit. Ein Anmeldeendpunkt oder eine Suchfunktion, die die Datenbank stark belastet, verdient eine viel strengere Begrenzung als das Abrufen einer statischen Liste. Eine großzügige Begrenzung für alles ist meist zu lasch, wo es darauf ankommt.
Wie vermeide ich, dass berechtigte Nutzer behindert werden?
Messen Sie zuerst, wie Ihre API in der Praxis genutzt wird, und legen Sie die Begrenzung deutlich über die übliche Spitzenlast. Führen Sie sie danach zunächst im Warnmodus ein, damit Sie Überschreitungen sehen, ohne etwas zu blockieren, und passen Sie an, bevor Sie durchsetzen.
Hilft eine Begrenzung gegen einen verteilten Angriff?
Nur teilweise. Ein Angreifer, der Tausende IP-Adressen einsetzt, umgeht eine Begrenzung je Adresse. Deshalb ist eine Begrenzung je Konto wichtig, und deshalb sind zusätzliche Maßnahmen auf Netzwerkebene nötig, etwa bei Ihrem CDN oder Anbieter.
Verwandte Artikel
- SchwachstellenCWE-639A01:2021Unzureichende Autorisierung auf Objektebene in APIsEine API, die nur prüft, ob Sie angemeldet sind, nicht aber, ob dieser Datensatz Ihnen gehört, gibt fremde Daten preis. Lesen Sie, wie Sie das erzwingen.
- 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-307A07:2021Brute Force und Credential StuffingAngreifer raten Passwörter oder spielen geleakte Anmeldedaten erneut ein. Lesen Sie, welche Grenzen und welcher zweite Faktor beides stoppen.
- SchwachstellenCWE-213A01:2021API-Antworten enthalten zu viele DatenEine API, die vollständige Datensätze zurückgibt und das Filtern dem Frontend überlässt, gibt Felder preis, die niemand sehen sollte.
- SchwachstellenCWE-1327A05:2021Unnötige Dienste aus dem Internet erreichbarDatenbanken, Verwaltungsports und Überwachungsoberflächen am Internet werden binnen Minuten gefunden. Lesen Sie, wie Sie diese Fläche verkleinern.