Mit einer konkreten Zusage beginnen
Nehmen wir eine fiktive API für kostenlose Beratungstermine. Ein Konto darf höchstens eine aktive Reservierung besitzen; ein Termin hat eine begrenzte Zahl freier Plätze. Die Nutzer dürfen ihre eigenen Reservierungen stornieren. Das klingt einfach, enthält aber mehrere verschiedene Entscheidungen: Wer ist das Konto? Welche Zustände zählen als aktiv? Wann wird ein Platz wieder frei? Was passiert, wenn zwei Anfragen gleichzeitig eintreffen?
Schreiben Sie diese Regeln mit den Fachverantwortlichen auf, bevor Sie Schwellen oder Sperren programmieren. Eine technische Umsetzung kann keine unausgesprochene Ausnahme korrekt erraten. Beispielsweise müssen Sie festlegen, ob eine abgelaufene Reservierung noch einen Platz belegt und ob ein freigegebener Ersatztermin die bisherige Reservierung beendet.
OWASP behandelt den Missbrauch sensibler Geschäftsabläufe ausdrücklich auch dann, wenn keine klassische Implementierungslücke nötig ist. Ein automatisierbarer erlaubter Ablauf kann allein durch Menge oder Kombination schaden. Die Entscheidung, welche Nutzung noch beabsichtigt ist, bleibt eine fachliche Aufgabe. OWASP API6:2023.
Rechte und Zustand bei jedem Übergang prüfen
Ein Ablauf lässt sich als wenige benannte Zustände beschreiben. Für die Reservierung könnten das „angefragt“, „bestätigt“, „storniert“ und „abgelaufen“ sein. Nicht jeder Wechsel ist erlaubt:
Bei schmaler Ansicht können Sie die Tabelle seitlich scrollen.
| Aktion | Voraussetzung | Beabsichtigte Wirkung |
|---|---|---|
| Reservierung bestätigen | Eigene Anfrage, noch gültig, Kapazität frei, Kontoregel erfüllt | Platz verbindlich zuordnen und Zustand ändern |
| Reservierung stornieren | Eigene aktive Reservierung, Stornierung nach der Geschäftsregel erlaubt | Zustand ändern und Platz genau einmal freigeben |
| Anfrage ablaufen lassen | Frist abgelaufen, noch nicht bestätigt | Anfrage beenden; keine bestätigte Reservierung aufheben |
| Reservierung administrativ ändern | Eigene Verwaltungsberechtigung und dokumentierter Grund | Gesondert erlaubten Übergang nachvollziehbar ausführen |
Diese Tabelle ist ein synthetisches Beispiel, keine allgemeine Terminregel. Ihr Zweck ist, fehlende Entscheidungen sichtbar zu machen.
Der Server ermittelt den aktuellen Zustand aus einer verlässlichen Quelle. Vom Client übermittelte Felder wie „freigegeben“ oder „Restkapazität“ sind keine Autorität. Auch ein deaktivierter Knopf im Frontend verhindert keinen direkten API-Aufruf. Die Feldrechte legen fest, welche Informationen ein Client überhaupt setzen darf.
Autorisierung und Zustandsprüfung ergänzen sich. Wer eine Reservierung grundsätzlich bearbeiten darf, darf sie nicht deshalb aus jedem Zustand heraus ändern. Umgekehrt verleiht ein erlaubter Zustand keine Rechte auf fremde Reservierungen. Die Objektberechtigung muss für dieselbe Aktion gelten.
Gleichzeitige Aufrufe müssen dieselbe Regel einhalten
Ein häufiger Fehler besteht aus zwei getrennten Schritten: erst prüfen, ob noch ein Platz frei ist, später den Platz abbuchen. Zwei Anfragen können beide denselben freien Platz sehen. Dass jeder Schritt schnell ist, beseitigt dieses Zeitfenster nicht.
Eine Möglichkeit für eine einzelne Kapazitätszeile ist eine bedingte Aktualisierung:
UPDATE demo_slot
SET remaining = remaining - 1
WHERE slot_id = :slot_id
AND remaining > 0;
Der Anwendungsablauf darf nur bei genau einer betroffenen Zeile fortfahren. Reservierungseintrag, Kontoregel und Kapazitätsänderung müssen in eine passende gemeinsame Transaktion beziehungsweise ein gleichwertiges konsistentes Verfahren eingebunden sein. Das Beispiel allein erfüllt die vollständige Reservierungsregel noch nicht.
Bei PostgreSQL prüft eine konkurrierende Aktualisierung unter Read Committed nach einer zwischenzeitlichen Änderung die WHERE-Bedingung an der aktualisierten Zeile erneut. Das trägt den gezeigten Einzelzeilenansatz. Regeln über mehrere Zeilen, Tabellen oder Fremdsysteme brauchen eine eigene Betrachtung; ein beliebiges SELECT innerhalb einer Transaktion sperrt nicht automatisch jede relevante Konkurrenz aus. PostgreSQL 18: Transaction Isolation, Abschnitt 13.2.1.
Wählen Sie Sperren, Eindeutigkeitsbedingungen, bedingte Zustandswechsel oder geeignete Isolation nach der konkreten Invariante. Eine Invariante ist die Bedingung, die nach jedem abgeschlossenen Vorgang gelten muss, etwa „Restkapazität ist nie negativ“. Falls eine Datenbank einen Konflikt meldet, braucht der gesamte fachliche Vorgang einen sicheren Umgang damit. Eine einzelne Teilanweisung losgelöst zu wiederholen kann andere Ergebnisse erzeugen.
OWASP empfiehlt für solche Abläufe eine ausdrückliche Zustandsmodellierung, serverseitig maßgebliche Werte und atomare Entscheidungen. Die Umsetzung bleibt vom verwendeten Speicher und Ablauf abhängig. OWASP: Business Logic Security.
Idempotenz, Mengenregeln und Rate-Limits lösen verschiedene Aufgaben
Idempotenz hilft, mehrere Zustellversuche desselben Auftrags wiederzuerkennen. Sie verhindert nicht, dass jemand mehrere neue Aufträge mit jeweils neuen Kennungen anlegt. Für „höchstens eine aktive Reservierung pro Konto“ benötigen Sie deshalb zusätzlich eine fachliche Eindeutigkeit oder eine gleichwertige durchgesetzte Regel.
Ein Rate-Limit begrenzt die Häufigkeit oder Ressourcenlast. Auch zehn erlaubte Aufrufe können zehn Plätze blockieren, obwohl fachlich nur einer vorgesehen war. Umgekehrt muss eine langsame legitime Aktion keine unbeschränkte Berechtigung bekommen, bloß weil sie unter der technischen Schwelle bleibt.
Denken Sie bei Mengenregeln an die maßgebliche Identität. Eine Grenze je API-Schlüssel kann durch mehrere legitime Schlüssel derselben Organisation fachlich am Ziel vorbeigehen. Eine Regel „einmal pro Person“ verlangt außerdem eine geeignete, verhältnismäßige Identitätsentscheidung; eine IP-Adresse ist nicht automatisch eine Person. Der Artikel legt kein Identifizierungsverfahren und keine rechtliche Grundlage dafür fest.
Berücksichtigen Sie das Ende eines Vorgangs ebenso wie seinen Beginn. Zwei Stornierungen dürfen denselben Platz nicht zweimal freigeben. Ein verspätetes Ablaufereignis darf eine inzwischen bestätigte Reservierung nicht rückgängig machen. Prüfen Sie vor dem Wechsel den aktuellen Zustand und speichern Sie, welche Wirkung schon zugeordnet wurde.
Externe Wirkungen und Rücknahmen ausdrücklich planen
Eine lokale Transaktion kann nicht ohne Weiteres eine externe Nachricht, Zahlung oder Partnerreservierung zurückrollen. Wenn solche Wirkungen nötig sind, speichern Sie zunächst einen nachvollziehbaren Auftrag und legen fest, wie Verarbeitung, Ergebnisabgleich und Wiederholung funktionieren. Der Ratgeber zu externen APIs behandelt diese Grenze.
Eine fachliche Gegenaktion ist etwas anderes als das Vergessen des ersten Auftrags. Das Stornieren einer Reservierung kann eine eigene berechtigte und protokollierte Aktion sein; ein bereits versandter Hinweis lässt sich dagegen nicht zurückholen. Benennen Sie mögliche Teilergebnisse und einen Zustand für ungeklärte Fälle.
Auch die Rücknahme einer neuen Sicherheitsregel braucht diese Betrachtung. Wenn eine neue Begrenzung zu viele legitime Vorgänge blockiert, sichern Sie zunächst die betroffenen Auftragskennungen und den letzten stabilen Zustand. Nehmen Sie die fehlerhafte Konfiguration gezielt zurück. Bereits durchgesetzte Einmaligkeits- oder Kapazitätsbedingungen sollten dadurch nicht verschwinden. Eine automatische Massenausführung zuvor abgewiesener Aufträge wäre ein neuer fachlicher Vorgang und benötigt eigene Bedingungen.
Den Ablauf mit eigenen Daten nachweisen
Prüfen Sie den Vertrag in einer freigegebenen isolierten Umgebung. Beginnen Sie mit einem normalen erlaubten Ablauf. Vergleichen Sie anschließend dieselben Aktionen aus dem falschen Zustand, mit einem anderen Testkonto und nach Ablauf der Frist. Verwenden Sie eigene synthetische Objekte; fremde Kundenkennungen sind dafür nicht nötig.
Für das Terminbeispiel gehören außerdem zwei kontrolliert gleichzeitig gestartete Bestätigungen auf den letzten Platz zum Nachweis. Am Ende darf höchstens eine erfolgreich sein; die Kapazität muss zum tatsächlichen Reservierungsbestand passen. Wiederholen Sie eine Stornierung und liefern Sie ein verspätetes Ablaufereignis. Prüfen Sie den dauerhaften Endzustand, nicht nur die HTTP-Statuscodes.
Das SQL-Beispiel illustriert nur die bedingte Änderung einer Zeile. Es wurde hier nicht unter PostgreSQL oder mit echter konkurrierender Ausführung erprobt. Ihre konkrete Transaktion, Fehlerrücknahme und ein möglicher externer Effekt benötigen deshalb eigene Integrationstests.
Regelverletzungen sichtbar machen
Erfassen Sie im Betrieb abgewiesene Zustandswechsel, Konflikte und ungeklärte Aufträge mit einem verlässlichen Grund und einer internen Korrelation. Ein Anstieg kann auf einen Clientfehler, einen geänderten Ablauf oder Missbrauch hinweisen. Er ist für sich noch kein Angriffsbeweis. Logging und Monitoring verbindet diese Signale mit einer verantworteten Reaktion.
Ein sauberer HTTP-Header und eine gute öffentliche Checkbewertung sagen nichts darüber aus, ob die Terminregel eingehalten wird. Der API Security Check prüft diese Geschäftsabläufe nicht. Der passende nächste Schritt ist ein dokumentierter Regelvertrag mit Entwicklung und Fachverantwortlichen sowie die gezielte Prüfung eigener API-Zusagen.
Quellen und Stand
Quellenstand: 27. September 2026. Die Links stehen zusätzlich bei den jeweils begründeten Aussagen.