Veröffentlicht am 26. August 2026 · 3 Min. Lesezeit
Ich habe gezählt, wie viele meiner API-Routen wirklich geschützt sind. Die Suche pro Datei log
Mein Panel hat heute über 240 API-Routen. Jede von ihnen beginnt mit derselben Zeile:
if (!(await isAuthed())) return new Response(null, { status: 401 });
Es gibt keine Schicht, die mir das abnimmt. In diesem Framework liegt das Verzeichnis /api außerhalb der Reichweite der Middleware, die gesamte Zugriffskontrolle besteht also aus dieser einen Zeile, wiederholt in jeder Datei einzeln. Sie zu vergessen erzeugt kein Symptom: Der Code kompiliert, das Panel läuft, und die Route steht jedem offen, der die Adresse kennt.
Ich wollte zählen, wie viele es wirklich sind.
Die erste Antwort war falsch
Der Reflex: die Dateien zählen, die isAuthed enthalten, und mit der Zahl der Routendateien vergleichen. Das Ergebnis sah gut aus — fast alle.
Fast. Ich sah mir die an, die dieses „fast" ausmachten, und stieß auf so etwas:
// ÖFFENTLICHE Route — bewusst ohne isAuthed(): Der Kunde öffnet sie
// über einen Link aus einer E-Mail, es gibt hier also keine Sitzung.
Die Datei erwähnte isAuthed. In einem Kommentar. Der begründete, warum es fehlt.
Solcher Stellen gab es fünf. Meine erste Zählung verbuchte jede davon als „geschützt", weil ich eine Zeichenkette in einer Datei suchte, statt die Frage zu beantworten, die mich wirklich interessierte.
Der zweite Fehler: Eine Datei ist keine Route
Auch nach dem Aussortieren der Kommentare ergibt das Zählen pro Datei keinen Sinn, denn eine Datei kann mehrere HTTP-Methoden bedienen. Eine typische Route sieht so aus:
export async function GET() { … }
export async function PATCH(){ … }
export async function DELETE(){ … }
Steht die Prüfung in GET, hat aber jemand später DELETE ergänzt und sie vergessen — dann „enthält die Datei isAuthed" nach wie vor. Die Suche sagt: geschützt. Die Wirklichkeit: Den Datensatz löschen kann jeder.
Die richtige Zähleinheit ist der HTTP-Handler, nicht die Datei. Erst diese Rechnung beantwortet die Frage „ist jeder Eingang ins System verschlossen".
Wie ich es am Ende gezählt habe
Ich habe alle exportierten Funktionen GET/POST/PATCH/PUT/DELETE im Routenverzeichnis aufgelistet und dann für jede geprüft, ob die Sitzungsprüfung in ihrem Rumpf steht und nicht irgendwo in der Datei. Dazu eine getrennte Liste der Routen, die absichtlich öffentlich sind — der Kunde nimmt ein Angebot an, holt ein Dokument über einen Link ab, das Kontaktformular — jede mit einer kurzen Begründung, warum sie offen stehen darf.
Das Ergebnis ist langweilig, und genau darum geht es: zwei Listen, die man in fünf Minuten durchsieht, und die Frage „wie viele Routen sind ungeschützt" hat jetzt eine Zahl als Antwort statt eines Eindrucks.
Was daraus allgemeiner folgt
Eine Textsuche beantwortet eine Frage über Text, nicht über Verhalten. Das klingt banal und ist deshalb gefährlich: Das Ergebnis sieht aus wie eine Messung und ist doch nur eine Trefferzahl. Jedes Mal, wenn ich aus einer solchen Suche einen Schluss ziehe, muss ich mich fragen, ob das Gezählte das Gefragte ist.
Sicherheit, die auf dem Wiederholen derselben Zeile beruht, beruht auf dem Gedächtnis. Auf Dauer sollte das eine Schranke sein, durch die man nicht durch Vergessen hindurchkommt. Heute habe ich eine Liste und einen Test, der sie prüft — bewusst weniger als eine Schranke, aber deutlich mehr als Hoffnung.
Öffentlich kann richtig sein — vorausgesetzt, es ist aufgeschrieben. Fünf Routen stehen mit Absicht offen. Der Unterschied zwischen einer bewussten Ausnahme und einem Loch besteht einzig darin, dass jemand festgehalten hat, was wovon ist. Eine undokumentierte Ausnahme ist ein halbes Jahr später nicht von einem Versehen zu unterscheiden — nicht einmal für den Autor.
Das war ein Teil einer Prüfung, die ich an meinem eigenen System selbst durchgeführt habe, ohne externen Auditor. Ich behaupte nicht, dass sie vollständig ist — ich behaupte, dass ich danach weiß, wie viele Routen ich habe und welche davon offen stehen, und dass ich davor nur eine Vermutung hatte.

Patryk Piecyk
Warschau · Junior-Implementierungsberater · ab sofort verfügbar
Siebeneinhalb Jahre habe ich in einem deutschen Unternehmen gearbeitet, fünf davon habe ich sein Büro geführt: Aufträge, Rechnungen, Reklamationen, ERP. Seit Juni 2026 baue ich eigene Werkzeuge für genau diese Arbeit — ich bin kein gelernter Programmierer; der Code entsteht gemeinsam mit einem KI-Assistenten, Entwurf, Entscheidungen und Tests sind meine. Diese Notizen beschreiben, was in diesen Systemen kaputtging und was dabei herauskam.
Eine Frage zu diesem Text?
Schreiben Sie mir →