was Prüfer wirklich sehen wollen
Security-Prüfer öffnen ein OpenAPI-Dokument mit einer klaren Checkliste im Kopf: Sind alle Endpoints authentifiziert? Sind Fehlerresponses vollständig dokumentiert? Werden Eingaben validiert? Wer diese Perspektive kennt, baut API-Dokumentation, die Audits beschleunigt, Findings reduziert und Vertrauen schafft.
Inhaltsverzeichnis
- 1. Die Audit-Perspektive: Was Prüfer als erstes suchen
- 2. Security Schemes: das erste Prüffeld
- 3. Public Endpoints explizit dokumentieren
- 4. Fehlerresponses vollständig modellieren
- 5. Input-Validierung in OpenAPI abbilden
- 6. Sensitive Daten in Schemas kennzeichnen
- 7. OWASP API Security Top 10 und OpenAPI
- 8. Rate Limiting und Quota in der Dokumentation
- 9. Audit-Findings: vermeidbar vs. unvermeidbar
- 10. Zusammenfassung
- 11. FAQ
1. Die Audit-Perspektive: Was Prüfer als erstes suchen
Ein Security-Prüfer, der ein OpenAPI-Dokument bekommt, beginnt nicht oben und liest linear durch. Er hat eine mentale Checkliste, die aus den häufigsten API-Sicherheitsproblemen abgeleitet ist – üblicherweise orientiert an der OWASP API Security Top 10. Der erste Blick gilt der security-Konfiguration: Gibt es überhaupt Security Schemes? Sind sie global oder pro Endpoint definiert? Welche Endpoints haben explizit security: [] – also keinen Authentifizierungsschutz?
Der zweite Blick gilt den Response-Definitionen: Sind 401- und 403-Responses für alle authentifizierten Endpoints dokumentiert? Werden 422- oder 400-Responses bei Validierungsfehlern gezeigt? Fehlen diese Responses, ist das kein kosmetisches Problem – es signalisiert, dass die API möglicherweise keine Validierungsfehler korrekt behandelt und potenziell sensitive Informationen in Fehlermeldungen preisgibt.
Der dritte Blick gilt den Schemas: Werden Integer-Felder ohne Minimum/Maximum definiert? Strings ohne maxLength? Arrays ohne maxItems? Diese Lücken in der Input-Validierungsdokumentation sind ein Hinweis auf mögliche Injection-Angriffsvektoren. Ein OpenAPI-Dokument, das diese Felder vollständig ausfüllt, senkt den Aufwand für den Prüfer erheblich und zeigt, dass das Entwicklungsteam mit den relevanten Sicherheitsanforderungen vertraut ist.
2. Security Schemes: das erste Prüffeld
Das Security-Scheme-Setup ist das erste, was ein Prüfer detailliert analysiert. Fehlende Security Schemes für Endpoints, die Nutzerdaten zurückgeben, sind ein sofortiges High-Finding. Zu schwache Schemes (z. B. HTTP Basic Auth ohne TLS-Erzwingung) oder Schemes ohne Ablaufmechanismus (z. B. API-Keys ohne Rotation-Dokumentation) sind Medium-Findings. Ein Prüfer erwartet, dass die OpenAPI-Dokumentation diese Informationen explizit enthält – nicht, dass er in der Laufzeitkonfiguration nachschauen muss.
Besonders kritisch: Endpoints, die sensitive Operationen ausführen (Passwort ändern, Zahlungsdaten abrufen, Admin-Funktionen), sollten in der Dokumentation explizit höhere Anforderungen signalisieren – z. B. durch spezifische Scopes oder durch eine Beschreibung, die MFA-Anforderungen dokumentiert. OpenAPI selbst hat keinen MFA-Typ, aber das description-Feld des Security Schemes und der Endpoint-Beschreibung sind der richtige Ort.
# Security-focused OpenAPI — what auditors want to see
openapi: 3.1.0
info:
title: Shop API — Security Documented
version: 2.0.0
description: |
## Security Overview
This API uses JWT Bearer authentication for all endpoints.
Tokens expire after 3600 seconds. Refresh tokens expire after 7 days.
All endpoints enforce TLS 1.2+. Rate limiting: 100 requests/minute per token.
## Sensitive Operations
Endpoints under /admin require the admin:* scope.
Password-change endpoints require re-authentication within the last 5 minutes.
# Global security — explicitly set, not implied
security:
- BearerAuth: []
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
JWT with RS256 signing. Claims: sub, roles, exp, iat, jti.
Issued by: https://auth.mironsoft.de
JWKS endpoint: https://auth.mironsoft.de/.well-known/jwks.json
Token lifetime: 3600s. Refresh: POST /auth/refresh (7-day refresh token).
Revocation: POST /auth/revoke (immediate effect via jti blacklist).
paths:
/users/{id}/password:
put:
summary: Change user password
description: |
Requires re-authentication within the last 300 seconds.
Returns 403 if the re-auth window has expired.
security:
- BearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [currentPassword, newPassword]
properties:
currentPassword:
type: string
format: password
minLength: 8
maxLength: 128
newPassword:
type: string
format: password
minLength: 12
maxLength: 128
description: Must contain uppercase, lowercase, digit and special char.
responses:
'204': { description: Password changed }
'400': { description: Validation error — weak or malformed password }
'401': { description: Missing or expired token }
'403': { description: Re-auth window expired or wrong current password }
'429': { description: Too many password-change attempts — try again in 15m }
3. Public Endpoints explizit dokumentieren
Endpoints ohne Authentifizierung sind nicht per se ein Problem – Health-Checks, öffentliche Produktlisten und Login-Endpoints müssen ohne Credential-Pflege erreichbar sein. Was Prüfer aber sehen wollen: Dass diese Endpoints bewusst und explizit als public markiert sind, nicht einfach vergessen wurden. Ein explizites security: [] mit einer description, die erklärt, warum der Endpoint public ist, zeigt, dass der API-Designer das Security-Modell durchdacht hat.
Ein häufiges Audit-Finding: Ein Endpoint, der sensitive Daten zurückgibt (z. B. Produktpreise mit Margendaten), hat kein Security Scheme – nicht weil er public sein soll, sondern weil es vergessen wurde. In einer OpenAPI-Spezifikation ist dieser Unterschied nicht sichtbar: Beide sehen wie security: [] aus. Die Lösung ist eine vollständige Dokumentation aller Public-Endpoints mit ihrer Begründung in der Beschreibung.
4. Fehlerresponses vollständig modellieren
Vollständige Fehlerresponse-Definitionen sind eines der aussagekräftigsten Signale in einer OpenAPI-Spezifikation aus Audit-Perspektive. Eine API, die für jeden Endpoint nur den Erfolgsfall dokumentiert, gibt keine Auskunft darüber, wie sie mit Fehlern umgeht – und das ist genau das, was Prüfer wissen wollen. Unvollständige Fehlerresponses sind ein Hinweis auf mögliche Information-Disclosure-Probleme: Wenn die API keine definierten Fehlermeldungen hat, gibt sie möglicherweise Stack-Traces, Datenbankfehler oder interne Pfade zurück.
Die Mindestanforderung aus Audit-Sicht: Für jeden authentifizierten Endpoint müssen 401 (fehlender Token) und 403 (falsche Berechtigung) dokumentiert sein. Für Endpoints mit Input-Validierung muss 422 oder 400 dokumentiert sein, inkl. Schema der Fehlermeldung. Für Admin-Endpoints muss 404 statt 403 erwogen werden (Sicherheitsempfehlung: sensible Ressourcen bei fehlender Berechtigung nicht mit 403, sondern mit 404 antworten, um ihre Existenz nicht zu bestätigen).
# Complete error responses — what auditors expect
components:
schemas:
# Standard error envelope — reused across all error responses
ApiError:
type: object
required: [error]
properties:
error:
type: object
required: [code, message]
properties:
code:
type: string
description: Machine-readable error code (e.g. VALIDATION_FAILED)
example: VALIDATION_FAILED
message:
type: string
description: Human-readable error message. Never includes stack traces.
example: The request body is invalid.
details:
type: array
description: Field-level validation details (422 responses only)
items:
type: object
required: [field, message]
properties:
field: { type: string }
message: { type: string }
# Rate limit error
RateLimitError:
allOf:
- $ref: '#/components/schemas/ApiError'
- type: object
properties:
retryAfter:
type: integer
description: Seconds until the rate limit resets
responses:
Unauthorized:
description: Missing, invalid or expired authentication token.
headers:
WWW-Authenticate:
schema: { type: string }
example: 'Bearer realm="api.mironsoft.de", error="invalid_token"'
content:
application/json:
schema: { $ref: '#/components/schemas/ApiError' }
example:
error: { code: INVALID_TOKEN, message: Token is expired or malformed. }
Forbidden:
description: Authenticated but insufficient permissions.
content:
application/json:
schema: { $ref: '#/components/schemas/ApiError' }
example:
error: { code: INSUFFICIENT_SCOPE, message: Required scope not present in token. }
UnprocessableEntity:
description: Request body failed validation.
content:
application/json:
schema: { $ref: '#/components/schemas/ApiError' }
TooManyRequests:
description: Rate limit exceeded.
headers:
Retry-After: { schema: { type: integer } }
X-RateLimit-Limit: { schema: { type: integer } }
X-RateLimit-Remaining: { schema: { type: integer } }
content:
application/json:
schema: { $ref: '#/components/schemas/RateLimitError' }
5. Input-Validierung in OpenAPI abbilden
Input-Validierungsconstraints in OpenAPI-Schemas sind nicht nur für die Dokumentation – sie sind ein Sicherheitssignal an Prüfer. Felder ohne maxLength auf String-Typen, ohne maximum auf Integer-Typen oder ohne maxItems auf Array-Typen weisen darauf hin, dass möglicherweise keine Eingabegrenzen implementiert sind. Das ist ein Angriffspunkt für Resource-Exhaustion-Angriffe und Injection-Versuche.
Aus Audit-Sicht besonders relevant: format-Felder signalisieren, dass spezifische Formatvalidierung stattfindet. format: email zeigt, dass E-Mail-Adressen validiert werden. format: uuid für ID-Felder zeigt, dass ID-Injection durch Integer-Enumeration verhindert wird. pattern für kritische Felder (z. B. Telefonnummern, Postleitzahlen) zeigt, dass Regex-Validierung im Einsatz ist. Alle diese Felder in OpenAPI-Schemas zu dokumentieren kostet wenig Aufwand, macht Audits aber erheblich effizienter.
6. Sensitive Daten in Schemas kennzeichnen
OpenAPI 3.1 (basierend auf JSON Schema) hat das Keyword writeOnly und readOnly, die in Sicherheitsaudits wichtig sind. Passwörter, Tokens und andere sensitive Credentials sollten als writeOnly: true markiert sein – das signalisiert, dass diese Felder nur im Request-Body erscheinen und nie in Responses zurückgegeben werden. Felder, die im Response erscheinen, aber nie im Request (z. B. interne IDs, Zeitstempel) sollten readOnly: true haben.
Das format: password-Keyword ist ebenfalls relevant: Es zeigt an, dass das Feld ein Passwort enthält und Tooling es entsprechend behandeln soll (z. B. Maskierung in Swagger-UI). Sensitive Felder wie Kreditkartennummern oder Sozialversicherungsnummern können mit einer Custom-Extension wie x-sensitive: true markiert werden – diese Extension hat keine native OpenAPI-Semantik, aber sie ist für Security-Tooling und menschliche Prüfer ein klares Signal.
7. OWASP API Security Top 10 und OpenAPI
Die OWASP API Security Top 10 (2023) listet die häufigsten API-Sicherheitsprobleme und hat direkte Entsprechungen in OpenAPI-Dokumenten. API1 (Broken Object Level Authorization) lässt sich durch vollständige Dokumentation der 401/403-Responses und explizite Scope-Anforderungen pro Endpoint adressieren. API3 (Broken Object Property Level Authorization) ist in der OpenAPI-Modellierung relevant: Wenn unterschiedliche Rollen unterschiedliche Felder sehen dürfen, sollte das durch separate Response-Schemas dokumentiert werden.
API8 (Security Misconfiguration) ist der häufigste Fund, der direkt aus OpenAPI-Dokumenten abgeleitet werden kann: fehlende Security Schemes, undokumentierte Public Endpoints, fehlende Error-Responses. Ein Prüfer, der API8 bewertet, liest das OpenAPI-Dokument und vergleicht es mit der Laufzeit-API. Diskrepanzen zwischen Dokumentation und Implementierung sind ein sofortiges Finding – die Dokumentation ist dann entweder veraltet oder die Implementierung entspricht nicht dem Design.
| OWASP API Finding | OpenAPI-Signal | Adressierung in OpenAPI | Severity |
|---|---|---|---|
| API1: Broken Object Auth | Kein 403 für Endpoints mit ID-Parametern | 403-Response + Scope-Anforderung dokumentieren | High |
| API3: Excessive Data Exposure | Response-Schema enthält sensitive Felder ohne readOnly | writeOnly/readOnly + format: password korrekt setzen | Medium |
| API4: Resource Exhaustion | Keine maxLength/maxItems in Schemas | Constraints konsequent dokumentieren | Medium |
| API8: Security Misconfiguration | Fehlende Security Schemes oder undokumentierte Public Endpoints | Globale Security + explizites security: [] für Public | High |
8. Rate Limiting und Quota in der Dokumentation
Rate Limiting ist in OpenAPI 3.x kein nativer Mechanismus, aber Prüfer erwarten seine Dokumentation. Die Empfehlung: Rate-Limiting-Headers (X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After) in den 429-Response-Definitionen dokumentieren. Das zeigt Prüfern, dass Rate Limiting implementiert ist und die API darüber informiert. Einige Teams nutzen Custom-Extensions wie x-rate-limit: 100/min auf Operationsebene – diese haben keine native Semantik, sind aber für Security-Tools und Prüfer ein klares Signal.
Ein oft übersehenes Detail: Unterschiedliche Rate Limits für unterschiedliche Rollen (z. B. 100 Requests/Minute für Standard-Nutzer, 1000 für Premium) sollten in der Beschreibung des Endpoints oder des Security Schemes dokumentiert werden. Das verhindert Missverständnisse beim Testen und gibt Prüfern die Information, die sie für die Bewertung von Denial-of-Service-Risiken benötigen.
# Rate limiting — documented via responses and headers
paths:
/products/search:
get:
summary: Search products
description: |
Rate limit: 100 requests/minute per authenticated token.
Unauthenticated requests: 10 requests/minute per IP.
Exceeding the limit returns 429 with Retry-After header.
security:
- BearerAuth: []
- {} # also allows unauthenticated (with lower rate limit)
parameters:
- name: q
in: query
required: true
schema:
type: string
minLength: 2
maxLength: 200 # prevent abuse via very long search queries
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100 # cap: prevent bulk scraping via high limit values
default: 20
responses:
'200':
description: Search results
headers:
X-RateLimit-Limit:
description: Requests allowed per minute for this token/IP
schema: { type: integer }
X-RateLimit-Remaining:
description: Requests remaining in current window
schema: { type: integer }
X-RateLimit-Reset:
description: Unix timestamp when the rate limit window resets
schema: { type: integer }
'400':
description: Query too short or too long
$ref: '#/components/responses/UnprocessableEntity'
'429':
description: Rate limit exceeded
$ref: '#/components/responses/TooManyRequests'
10. Zusammenfassung
Security Audits für REST APIs werden durch vollständige OpenAPI-Dokumentation erheblich effizienter – und die Anzahl der Findings sinkt. Das wichtigste Ergebnis sorgfältiger Audit-orientierter Modellierung: Prüfer müssen weniger Zeit damit verbringen, herauszufinden, wie die API funktioniert, und mehr Zeit damit, ob sie sicher funktioniert. Security Schemes vollständig definieren, Public Endpoints explizit markieren, Fehlerresponses für alle relevanten Statuscodes dokumentieren und Input-Validation-Constraints in Schemas abbilden – das sind die vier Säulen einer audit-tauglichen OpenAPI-Spezifikation.
Der langfristige Nutzen geht über einzelne Audits hinaus: Ein OpenAPI-Dokument, das Security-Anforderungen vollständig dokumentiert, dient als lebendes Sicherheitskonzept. Neue Entwickler im Team sehen sofort, welche Authentifizierung, welche Scopes und welche Fehlerfälle erwartet werden. Automatisierte Sicherheitstools wie 42Crunch oder OWASP Zap können gegen die OpenAPI-Spezifikation validieren und Abweichungen zwischen Dokumentation und Implementierung automatisch erkennen.
OpenAPI Security Audit-Readiness — Das Wichtigste auf einen Blick
Security Schemes
Vollständig dokumentiert: Typ, Format, Ablauf, Revocation. Globales Security-Objekt gesetzt. Public Endpoints mit explizitem security: [] und Begründung.
Error Responses
401, 403, 422, 429 für alle relevanten Endpoints. Einheitliches Fehler-Schema ohne Stack-Traces. WWW-Authenticate-Header für 401.
Input-Validierung
maxLength, minimum, maximum, maxItems für alle Eingabefelder. format: uuid für IDs. format: password für Credentials. writeOnly für sensitive Felder.
OWASP Mapping
API1, API3, API4, API8 direkt durch OpenAPI-Dokumentation adressierbar. Automatisierte Validierung mit 42Crunch oder OWASP Zap.