Erfahre im kostenlosen eBook wie du mit OAuth2, API-Keys, JWT und einem Gateway APIs schützen kannst.
Dieser Artikel ist zuerst im Java Magazin 4.2026 unter dem Titel „Registrier’ dir deinen Admin: Wenn ein neues Feld zur Sicherheitslücke wird“ erschienen.
Schauen wir uns ein Webshop-API an, über das sich neue Benutzer registrieren können. Zu Beginn gibt es dort nur normale Nutzer ohne besondere Berechtigungen. Der entsprechende API-Aufruf sieht z. B. so aus wie in Listing 1.
Die Spring-Boot-Implementierung ist simpel: Der Controller nimmt Benutzername und Passwort entgegen und legt einen neuen User in der Datenbank an. Wichtig dabei: In der ersten Version hat die Klasse User nur id, username und password als Felder (kein Rollenfeld). Der Code könnte etwa so aussehen wie in Listing 2 gezeigt.
Hier bekommt jeder neue Benutzer implizit die Standardrolle (z.B. USER), weil es gar keine anderen gibt. Ein Beispiel für ein Registrierungsformular auf der Website des Webshops zeigt Abbildung 1.

Nun kommt ein Featurewunsch: Man will zwischen Kunden und Administratoren unterscheiden, also Benutzerrollen einführen. Der schnellste Weg: Die bestehende User-Klasse um ein Feld role erweitern. Der Entwickler passt also den Code minimal an: Die Datenklasse User erhält ein neues Feld role. Den entsprechenden Diff zeigt Listing 3.
Auf den ersten Blick scheint das zu funktionieren: Das Registrierungsformular auf der Website bleibt, wie es ist. Nur im Backend kann die Anwendung jetzt zwischen „Kunde“ und „Administrator“ unterscheiden. Doch was wurde übersehen? Durch diese Änderung kann jetzt jeder, der den API-Aufruf kennt, versuchen, sich mit einer beliebigen Rolle zu registrieren.
Angreiferin Mallory wittert ihre Chance. Sie schickt direkt einen API Request und gibt dabei manuell die Rolle ADMIN mit (Listing 4).
Was passiert? Unsere Anwendung übernimmt arglos alle Felder und legt in der Datenbank einen Benutzer mallory mit Passwort 123456 und der Rolle ADMIN an. Es findet keine Prüfung statt, ob der Aufrufer das darf. Das Backend vertraut blind dem Request. Mallory kann sich nun einloggen und hat volle Adminrechte.
Das ist ein klassischer Fall von Mass Assignment: Die Anwendung bindet Request-Daten automatisch an interne Objekte, ohne sicherheitskritische Felder auszuschließen. Angreifer können so versteckte oder eigentlich schreibgeschützte Properties setzen, die vom Client nicht kommen dürften, in unserem Fall die Adminrolle. Aus einem harmlosen Featurewunsch ist eine gravierende Sicherheitslücke geworden: vertikale Rechteausweitung (ein normaler Nutzer verschafft sich Adminrechte). Kein Wunder, dass BOPLA auf Platz 3 in den OWASP API Security Top 10 auftaucht (Abb. 2).

Solche Lücken entstehen oft aus Bequemlichkeit oder aufgrund falscher Annahmen. Der Entwickler dachte vielleicht: „Unsere eigene Frontend-App wird keine Adminregistrierung schicken.“ Das mag stimmen. Aber kann man garantieren, dass nur die eigene App das API aufruft? Nein. Sobald ein API öffentlich ist, kann jeder darauf zugreifen. Mobile-App, Web-Frontend, Drittsysteme … Alles, was der URL kennt, kann Requests schicken. Im Idealfall ist das API geschützt (Authentifizierung), aber in unserem Fall soll die Registrierung ja offen und auf der Website möglich sein. Ein Angreifer kann sich die Netzwerkaufrufe der offiziellen App anschauen (z. B. via Browser-DevTools oder Mobile- Proxy) und dann mit eigenen Tools (Postman, cURL) die gleiche Anfrage mit manipulierten Daten senden. Wir haben keinerlei Kontrolle darüber, wer unsere HTTP-Schnittstelle anspricht. Das ist der fundamentale Unterschied zwischen internem Methodenaufruf und öffentlichem API.
Auch automatisierte Scanner entdecken so etwas nicht unbedingt, denn formal ist es kein Fehler: Das API erlaubt ja das Feld role (absichtlich oder unabsichtlich). Erst gezielte Abuse-Tests oder Sicherheitsreviews decken auf, dass sich hier jeder zum Admin befördern kann.
Frameworks wie Spring machen das Data Binding sehr bequem: Man kann direkt ein Domainobjekt als @RequestBody nutzen. Doch genau das ist das Problem: Ohne zusätzliche Vorkehrungen übernimmt Spring alle Felder aus dem JSON ins Objekt. Was nicht ausdrücklich ignoriert oder validiert wird, landet ungehindert dort. Solange die Klasse User kein role hatte, war alles gut, doch jetzt haben wir uns damit eine Hintertür eingebaut.
Wie schützt man sich davor? Die wichtigste Regel lautet: „Niemals blind den Request-Daten trauen!“ Konkret gibt es mehrere Ansätze, um Mass Assignment zu verhindern. Am besten kombiniert man mehrere derjenigen, die wir im Folgenden beschreiben.
Verwenden Sie für den Request ein gesondertes DTO, anstatt direkt die JPA-Entität User zu befüllen, z. B. UserRegistrationDto nur mit username und password, ohne role-Feld darin. Der Controller mappt dieses DTO dann ins Datenbankmodell und vergibt dabei die Rolle serverseitig. Weil das DTO gar keinen role- Parameter erlaubt, kann ein Angreifer auch keinen einschleusen. Dieses Vorgehen – also explizit zu bestimmen, welche Felder übernommen werden – ist die sicherste Gegenmaßnahme gegen Mass Assignment. In vielen Webframeworks gehört Feld-Whitelisting zum Standard; in Spring/Java ist es am einfachsten, mittels gezielter Konfiguration (@JsonIgnore bei JSON-APIs, WebDataBinder bei Formularen) oder DTOs sicherzustellen, dass unerwünschte Felder ignoriert werden. Die Implementierung könnte so aussehen wie in Listing 5 oder Listing 6.
Hier wird das Passwort gehasht gespeichert, und die Rolle ignoriert jegliche Eingabe (immer auf USER gesetzt). Die Response enthält ebenfalls nur ausgewählte Felder (kein Passworthash). Dadurch ist es egal, was der Client schickt. Die Rolle Admin wird niemand außer uns selbst vergeben.
Ergänzend sollte jede Eingabe validiert werden. Bean Validation (z.B. mit @NotBlank, @Size usw.) stellt sicher, dass Felder wie username und password sinnvolle Werte enthalten. Wenn man dem Client erlaubt, ein Rollenfeld mitzugeben (z.B. zur Unterscheidung zwischen USER und SELLER), muss die Validierung sicherstellen, dass nur erlaubte Rollenwerte akzeptiert werden. Ein Wert wie ADMIN sollte in diesem Fall explizit abgelehnt oder ignoriert werden.
In Spring Boot werden unbekannte Felder im JSONRequest standardmäßig nicht übernommen, allerdings auch nicht beanstandet. Das liegt daran, dass die Einstellung FAIL_ON_UNKNOWN_PROPERTIES im verwendeten ObjectMapper per Default auf false steht. Um unbekannte Felder dennoch zu übernehmen (was in sicherheitskritischen Kontexten nicht empfohlen wird), müsste z.B. @JsonAnySetter verwendet werden.
Einige JavaScript-Frameworks wie Express in Kombination mit celebrate/Joi bieten ebenfalls Möglichkeiten zur Feldkontrolle. Dort kann man mit der Option stripUnknown (standardmäßig false) festlegen, dass unbekannte Felder automatisch entfernt werden. Ein manipuliertes Feld wie role: „ADMIN“ würde so gar nicht im verarbeiteten Objekt auftauchen.
Achtung: Das stillschweigende Entfernen unbekannter Felder hat Vor- und Nachteile. Zwar wird ein potenzieller Angriff dadurch neutralisiert, doch bleibt er möglicherweise unbemerkt. In sicherheitskritischen Anwendungen ist es daher oft sinnvoller, solche Felder mit einem Fehler zu quittieren oder zumindest zu protokollieren, um potenzielle Missbrauchsversuche nachvollziehen zu können.
Überlegen Sie beim Design, ob ein normaler Registrierungs- Endpoint überhaupt Admins oder andere privilegierte Nutzer anlegen können muss. Eigentlich muss er das nicht. Die Vergabe von Adminrechten gehört in einen eigenen, geschützten Endpoint (z.B. /api/admin/users für eine Admin-User-Anlage oder eine Rollenänderung). Selbst wenn der Standard-Endpoint manipulierbar wäre, hätte ein gesendetes role-Feld dort keine Wirkung, weil es ignoriert würde. Dieses Prinzip der getrennten Pfade reduziert die Angriffsfläche enorm. Zusätzlich kann man solche Admin-Pfade gezielt absichern – etwa im Gateway nur für interne Aufrufe freigeben (z.B. externe Zugriffe auf /api/admin/* blockieren). So ist sichergestellt, dass ein externer Angreifer diese Funktionen gar nicht nutzen kann, selbst wenn er authentifiziert ist. Eine einfache, aber sehr effektive Maßnahme.
Änderungen an sicherheitsrelevanten Features sollten streng geprüft werden. Hier hätte ein einfacher Negativtest den Fehler gezeigt: der Versuch, einen Nutzer mit role: „ADMIN“ zu registrieren, und erwarten, dass das nicht funktioniert. Solche Tests gehören in die Testsuite, insbesondere wenn man weiß, dass gefährliche Felder im Spiel sind. Ebenso lohnt sich eine Codereview mit dem „Was wäre, wenn“-Blick. Ein Kollege hätte die Frage stellen können: „Kann jemand dieses neue Feld missbrauchen?“ Security-Scans (SAST/DAST) finden Mass Assignment leider nicht immer zuverlässig, aber manche Tools (z.B. CodeQL oder Fortify) haben Patterns, die Alarm schlagen, wenn ein Request-Objekt unkontrolliert in die Persistenzschicht fließt.
BOPLA betrifft auch die ungewollte Datenausgabe (Excessive Data Exposure). Achten Sie darauf, nur benötigte Felder zurückzugeben. In unserem Beispiel senden wir in der Response nur Username und Rolle – nicht etwa den Passworthash. Allgemeiner: Wenn z.B. GET /api/users/{id} implementiert wird, sollte ein normaler Nutzer darüber niemals vertrauliche Felder anderer sehen (z.B. isAdmin, creditCard, permissions etc.). Solche sensiblen Properties gehören entweder gar nicht in die Response oder müssen serverseitig gefiltert werden (z.B. mit @JsonIgnore oder gezielten DTOs für die Ausgabe).
Das Prinzip: Alles, was ein Client nicht unbedingt wissen muss, sollte er gar nicht erst zu Gesicht bekommen. So schließt man auch diese Hälfte der BOPLA-Problematik.
Nehmen wir an, der Entwickler übersieht die Sicherheitsproblematik beim Coding. Wie hätte man die Lücke vor dem Deployment bemerken können? Ein Schlüssel dazu ist die API-Dokumentation. Professionelle APIs haben eine OpenAPI-Spezifikation, die beschreibt, welche Felder ein Request haben darf (OpenAPI ist der Nachfolger von Swagger).
Fügen wir beispielsweise die Abhängigkeit org. springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14 zu unserem Spring-Boot-Projekt hinzu und rufen /v3/api-docs ab, so erhalten wir bereits eine OpenAPI-Definition unserer Schnittstelle. In unserem ursprünglichen Zustand sieht sie etwa so aus wie in Listing 7.
Hier sind nur id, username und password als erlaubte Felder definiert. Doch ein entscheidendes Detail fehlt: Die Eigenschaft additionalProperties ist nicht gesetzt. Das bedeutet, dass das API standardmäßig auch zusätzliche, nicht definierte Felder akzeptiert: ein potenzielles Einfallstor für Mass Assignment.
Die Einstellung additionalProperties: false bedeutet, dass keine weiteren Felder zugelassen sind. Eine extrem wichtige Sicherheitsvorgabe. Wir passen daher die OpenAPI-Beschreibung an (Listing 8).
Diese Änderung setzen wir selbstredend nicht manuell um, da das OpenAPI-Dokument generiert wurde. Stattdessen nutzen wir die Annotation io.swagger.v3.oas.annotations.media.Schema an der User-Klasse:
Was passiert nun, nachdem der Entwickler das role-Feld in der User-Klasse, wie in Listing 3 gezeigt wurde, hinzugefügt hat? Das generierte OpenAPI ändert sich (Listing 9).
Jetzt ist für jeden sichtbar (zumindest intern im Team): Im Registrierungs-Request gibt es plötzlich ein Feld role. Ein Security-Architekt würde sofort fragen, warum eine normale Registrierung eine Rolle akzeptieren soll. Diese Transparenz ist der erste Vorteil einer sauberen Spezifikation. Aber auch ohne menschlichen Blick kann man hier ansetzen: Mit Tools wie Spectral (ein OpenAPI Linter, siehe [4]) lässt sich die Einhaltung von API-Guidelines automatisiert prüfen.
Ein bewährtes Pattern ist, jede Objektdefinition in der Spec mit additionalProperties: false zu versehen (wie oben). Spectral kann so konfiguriert werden (bzw. es gibt vordefinierte OWASP-Regeln dafür), dass es einen Fehler wirft, wenn in einem Schema additionalProperties fehlt oder auf true steht. Damit wird sichergestellt, dass Entwickler alle erlaubten Felder explizit definieren. In unserem Beispiel wäre das bereits erfüllt gewesen, die Spec war streng. Hätte der Entwickler jedoch versäumt, die Spec zu aktualisieren, wäre die Diskrepanz offensichtlich:
Wie integriert man diese Ideen in den Entwicklungsprozess? Hier kommt APIOps ins Spiel. APIOps ist ein Ansatz analog zu GitOps, bei dem sowohl Code als auch API-Dokumentation und Gateway-Konfiguration in Git versioniert werden. In der Praxis könnte das so aussehen:

Dieser Prozess klingt aufwendig, ist aber für sicherheitskritische APIs extrem empfehlenswert. Er stellt sicher, dass Security-Themen nicht unter den Tisch fallen, sondern früh im Lifecycle diskutiert werden.
Ein großer Vorteil, wenn man die OpenAPI-Spezifikation so ernst nimmt: Man kann sie zur Laufzeit nutzen. Viele API Gateways können eingehende Anfragen strikt gegen die Spec prüfen. Das heißt, das Gateway lässt nur durch, was im Vertrag steht. In unserem Beispiel hätte ein Gateway im ursprünglichen Zustand einen Request mit unbekanntem Feld role abgelehnt. Hätte der Entwickler die Spec zwar angepasst, aber niemand das Okay dafür gegeben, wäre der neue Spec-Stand gar nicht erst ins Gateway gekommen.
Um das greifbar zu machen, zeigt Listing 10 ein Beispiel dafür, wie eine solche Gateway-Konfiguration aussehen könnte.
In diesem Membrane-Beispiel wird eine OpenAPIDatei (openapi.yaml) geladen und gegen alle Requests und Responses geprüft. Ein unerwartetes Feld führt automatisch zu einer Fehlermeldung („validation failed: property ‚role‘ is not allowed“, o. Ä.). Ähnliches geht auch mit anderen Gateways, z. B. Kong via Plug-in.
Listing 11 zeigt einen Ausschnitt einer deklarativen Kong-Konfiguration (per decK). Das Request-Validator- Plug-in prüft hier den JSON-Body: Erlaubt sind nur username und password (sonst nichts). Ein Angreifer- Request mit role würde vom Gateway mit „400 Bad Request“ abgelehnt, noch bevor unsere Anwendung irgendetwas davon sieht.
Natürlich muss man den Mehraufwand solcher Maßnahmen berücksichtigen. Nicht jedes kleine interne API rechtfertigt eine vollautomatisierte APIOps-Pipeline oder strikte Gateway-Filter. Doch in Bereichen mit hohen Sicherheitsanforderungen (externe APIs, kritische Daten) sind diese Mechanismen Gold wert. Sie fungieren als mehrfach gestaffelte Schutzmaßnahmen: sichere Entwicklung, strenge Spezifikation, automatisierte Checks, Gatekeeper vor der Anwendung. Kommt es doch zu einer unerwarteten Änderung, fängt eine der Schichten das Problem ab.
| Anzeichen | Beschreibung/Risiko |
| fehlendes additionalProperties: false | OpenAPI erlaubt zusätzliche Felder; Risiko: Angreifer können unerwartete Properties einschleusen (z.B. role) |
| direktes Binding von Domain-Objekten | Request-Daten werden ohne DTO oder Feld-Whitelist an JPA-Entitäten gebunden; Risiko: Mass Assignment |
| generische Setter oder z.B. BeanUtils.copyProperties() | kopiert alle Felder inkl. sensibler Properties; Risiko: Manipulation sicherheitskritischer Felder |
| PATCH-Endpunkte ohne Feldkontrolle | Teilaktualisierungen akzeptieren beliebige JSON-Felder; Risiko: versteckte Payload |
| keine Validierung erlaubter Werte | Rollen oder Statusfelder werden übernommen, ohne auf erlaubte Werte zu prüfen; Risiko: Rechteausweitung |
| fehlende Constraints in Datenbank oder ORM | DB akzeptiert beliebige Werte für Rollen oder Status; Risiko: Umgehung von Codechecks |
| ungefilterte Response-Serialisierung | Backend gibt komplette Objekte zurück; Risiko: sensitive Properties werden offengelegt |
| kein Logging bei unbekannten Feldern | unerwartete Felder werden stillschweigend ignoriert; Risiko: Angriffe bleiben unbemerkt |
| unzureichende Tests für negative Szenarien | Testsuite prüft nur den Happy Path; Risiko: Angriffe wie „role=ADMIN“ bleiben unentdeckt |
Entwickler sollten vor allem folgende Punkte im Hinterkopf behalten:
Für Architekten und Security-Teams sind vor allem folgende Punkte von Bedeutung:
Das „Registrier’ dir deinen Admin“-Szenario zeigt eindrücklich, wie aus einer kleinen Codeänderung eine gravierende Sicherheitslücke werden kann. Broken Object Property Level Authorization mag ein Zungenbrecher sein, doch dahinter stecken bekannte Probleme (Mass Assignment, Excessive Data Exposure), die vermeidbar sind. Mit sauberer Trennung von Schichten, strikten Schemas und mehrstufigen Prüfungen lässt sich diese Gefahr bannen. Entwickler sollten Eingaben niemals blind vertrauen, sondern immer nur genau das verarbeiten, was erlaubt ist. Architekten und Sicherheitsingenieure sollten darauf achten, dass APIs einen klaren Vertrag haben und dass Abweichungen davon auffallen, sei es durch Tools oder Prozesse.
Der Spoiler aus der Einleitung bewahrheitet sich also: „Registrier’ dir deinen Admin“ darf kein legitimes Feature sein. Mit den richtigen Maßnahmen stellen wir sicher, dass Adminrechte da bleiben, wo sie hingehören, und nicht versehentlich über die Benutzerregistrierung verteilt werden.
Lerne von unseren Autoren in der API Security Schulung.
Online Training
12. - 13. 10.2026
Jetzt anmelden
für 1.340,- €*
Schulungen in Bonn
Jetzt anmelden
für 1.470,- €*