Skip to content
IRC-CodingIRC-Coding
REST API SicherheitAuthentifizierungAutorisierungOAuth 2.0JWTRBACCORSAPI Security

REST API Sicherheit: Authentifizierung, Autorisierung und Schutzmaßnahmen

REST API Sicherheit: Authentifizierung vs. Autorisierung, OAuth 2.0, JWT, Session-Auth, RBAC, ABAC, CORS, CSRF und Best Practices.

S

schutzgeist

11 min read
REST API Sicherheit: Authentifizierung, Autorisierung und Schutzmaßnahmen

REST API Sicherheit: Authentifizierung, Autorisierung und Schutzmaßnahmen

REST API Sicherheit sorgt dafür, dass nur berechtigte Clients auf berechtigte Ressourcen zugreifen können. Wer APIs baut, muss Authentifizierung und Autorisierung verstehen — sie sind das Fundament jeder sicheren Schnittstelle.

Was ist REST API Sicherheit?

REST API Sicherheit umfasst alle Maßnahmen, die eine RESTful API vor unbefugtem Zugriff, Manipulation und Angriffen schützen. Sie beruht auf zwei Kernsäulen:

Authentifizierung beantwortet: Wer bist Du? Der Client beweist seine Identität durch Tokens, API-Keys, Zertifikate oder Session-Cookies.

Autorisierung beantwortet: Darfst Du das? Nach der Authentifizierung wird geprüft, ob der identifizierte Client die Berechtigung hat, die angefragte Aktion auszuführen.

Die Trennung ist essenziell. Ein authentifizierter Benutzer ist nicht automatisch autorisiert, alles zu tun. Ein Nutzer darf seine eigenen Daten lesen, aber nicht die anderer. Ein Admin darf mehr als ein Redakteur. Diese Unterscheidung wird durch Modelle wie RBAC (Role-Based Access Control) oder ABAC (Attribute-Based Access Control) abgebildet.

Wer nutzt REST API Sicherheit?

  • Backend-Entwickler implementieren Auth-Middleware und Autorisierungslogik
  • API-Designer definieren, welche Endpunkte welchen Schutz benötigen
  • DevOps-Engineers konfigurieren TLS, Rate Limiting und API Gateways
  • Security-Engineers auditieren APIs auf Schwachstellen
  • Frontend-Entwickler müssen Auth-Tokens korrekt mitsenden

Warum ist das Thema in der Informatik und für Prüfungen wichtig?

Die OWASP Top 10 listet Broken Access Control auf Platz 1 und Cryptographic Failures auf Platz 2 — beide betreffen direkt API-Sicherheit. In IHK-Prüfungen, im Informatikstudium und in Zertifizierungen werden regelmäßig die Unterschiede zwischen Authentifizierung und Autorisierung, OAuth 2.0, JWT und Sicherheitsheader abgefragt.

Kernkonzepte im Detail

Authentifizierungsverfahren für REST APIs

API-Key

Der Client sendet einen statischen Schlüssel im Header X-API-Key. Der Server vergleicht ihn mit seiner Datenbank.

Vorteile: simpel, gut für Server-to-Server-Kommunikation. Nachteile: kein Ablauf, keine feingranularen Rechte, bei Kompromittierung voller Zugriff.

Session-basierte Authentifizierung

Der Client sendet Credentials (Benutzername/Passwort). Der Server erstellt eine Session, speichert sie serverseitig und gibt eine Session-ID im Cookie zurück. Bei jeder weiteren Anfrage wird das Cookie automatisch mitgesendet.

Vorteile: serverseitige Kontrolle, Session kann jederzeit invalidiert werden. Nachteile: skaliert schlecht bei vielen Instanzen (Shared Session Store nötig), CSRF-Risiko bei Cookies.

Token-basierte Authentifizierung (JWT)

Der Client sendet Credentials. Der Server erstellt ein JSON Web Token (JWT), das Claims wie Benutzer-ID, Rollen und Ablaufzeit enthält. Das Token ist kryptografisch signiert. Der Client sendet es bei jeder Anfrage im Authorization: Bearer <token> Header.

Vorteile: zustandslos (stateless), skaliert gut, kein Session-Store nötig. Nachteile: Token kann vor Ablauf nicht einfach widerrufen werden (außer mit Revocation Lists oder Blacklists).

OAuth 2.0

OAuth 2.0 ist ein Framework für delegierte Autorisierung. Ein Client erhält ein Access Token von einem Authorization Server, nachdem der Resource Owner (der Nutzer) seine Zustimmung gegeben hat. Das Token erlaubt den Zugriff auf bestimmte Ressourcen für eine begrenzte Zeit.

Wichtige Flows:

  • Authorization Code Flow: Standard für Web-Apps mit Server-Backend
  • PKCE Flow: Für SPAs und mobile Apps ohne Client Secret
  • Client Credentials Flow: Für Server-to-Server-Kommunikation ohne Nutzerbeteiligung

Autorisierungsmodelle

RBAC (Role-Based Access Control)

Benutzer werden Rollen zugewiesen. Rollen haben Berechtigungen. Die Prüfung lautet: Hat der Benutzer die Rolle, die diese Aktion erlaubt?

Beispiel: Rolle admin darf alles, Rolle editor darf lesen und schreiben, Rolle viewer darf nur lesen.

Vorteile: einfach zu verstehen, gut für überschaubare Systeme. Nachteile: Rollenexplosion bei feingranularen Berechtigungen.

ABAC (Attribute-Based Access Control)

Die Zugriffskontrolle basiert auf Attributen von Subjekt, Ressource, Aktion und Umgebung. Die Prüfung lautet: Erfüllt die Kombination aller Attribute die Policy?

Beispiel: Ein Arzt darf Patientendaten nur während seiner Dienstzeit und nur für Patienten seiner Abteilung lesen.

Vorteile: sehr feingranular, policy-basiert. Nachteile: komplexer zu implementieren und zu warten.

Resource Owner / Ownership-basierte Autorisierung

Der Nutzer darf nur auf Ressourcen zugreifen, die ihm gehören. Eine Bestellung kann nur vom Eigentümer eingesehen werden. Die Prüfung erfordert eine Datenbankabfrage: Gehört diese Ressource zum authentifizierten Nutzer?

Weitere Sicherheitsmaßnahmen

TLS (Transport Layer Security)

Jede API muss über HTTPS laufen. Ohne TLS können Tokens und Credentials abgefangen werden. TLS verschlüsselt die Transportstrecke und garantiert die Integrität der übertragenen Daten.

CORS (Cross-Origin Resource Sharing)

CORS regelt, welche fremden Origins auf die API zugreifen dürfen. Der Server sendet Access-Control-Allow-Origin Header. Ohne korrekte CORS-Konfiguration können Browser-basierte Clients blockiert werden, oder schlimmer, beliebige Origins erhalten Zugriff.

CSRF-Schutz

Bei Cookie-basierter Authentifizierung besteht CSRF-Risiko. Ein Angreifer kann den Browser dazu bringen, ein Cookie automatisch mitzusenden. Schutzmaßnahmen: CSRF-Tokens, SameSite-Cookie-Attribut, Authorization Header statt Cookies.

Rate Limiting

Begrenzt die Anzahl der Anfragen pro Client in einem Zeitraum. Schützt vor Brute-Force-Angriffen, Credential Stuffing und DoS. Typisch: 100 Requests pro Minute pro Token.

Input Validation

Jede Eingabe muss validiert werden. SQL Injection, XSS und Command Injection entstehen durch fehlende oder unzureichende Validierung. Nutze Prepared Statements, Schema-Validierung und Whitelisting.

Warum ist REST API Sicherheit in der Praxis wichtig?

Eine unsichere API ist ein offenes Fenster zu Deinen Daten. Realistische Szenarien:

  • Token-Leck: Ein Access Token wird in Logs gespeichert oder in Client-Code hartkodiert. Ein Angreifer findet es und greift auf alle Daten des betroffenen Nutzers zu.
  • Broken Object Level Authorization (BOLA): Die API prüft nur, ob der Nutzer authentifiziert ist, aber nicht, ob er auf die angefragte Ressource zugreifen darf. Ein Nutzer ruft /api/orders/42 auf und sieht die Bestellung eines anderen Nutzers.
  • Mass Assignment: Der Client sendet ein Feld wie {"role":"admin"} beim Profil-Update. Der Server übernimmt es ungeprüft. Der Nutzer macht sich selbst zum Admin.
  • Kein Rate Limiting: Ein Angreifer probiert 10.000 Passwörter pro Sekunde durch. Ohne Rate Limiting bricht er das Passwort in Minuten.

Praxisbeispiel: Express.js API mit JWT und RBAC

Dieses Beispiel zeigt eine vollständige REST API mit Authentifizierung (JWT) und Autorisierung (RBAC). Es wurde gewählt, weil es die wichtigsten Konzepte in kompaktem Code vereint: Token-Erstellung, Middleware-basierte Auth-Prüfung, rollenbasierte Zugriffskontrolle und Ownership-Prüfung.

// auth-middleware.js
// Middleware: Verifiziert JWT aus dem Authorization Header
function authenticate(req, res, next) {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({
      error: 'UNAUTHORIZED',
      message: 'Authentifizierung erforderlich. Senden Sie einen Bearer Token.'
    });
  }

  const token = authHeader.split(' ')[1];
  try {
    // jwt.verify wirft eine Exception bei ungültigem oder abgelaufenem Token
    const payload = jwt.verify(token, process.env.JWT_SECRET);
    req.user = payload; // { userId: 42, role: 'editor', exp: 1234567890 }
    next();
  } catch (err) {
    return res.status(401).json({
      error: 'INVALID_TOKEN',
      message: 'Token ist ungültig oder abgelaufen.'
    });
  }
}

// Middleware: Prüft ob der Nutzer eine der erforderlichen Rollen hat
function authorize(...roles) {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({
        error: 'UNAUTHORIZED',
        message: 'Authentifizierung erforderlich.'
      });
    }
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({
        error: 'FORBIDDEN',
        message: `Erforderliche Rolle: ${roles.join(' oder ')}.`
      });
    }
    next();
  };
}

// Middleware: Prüft ob der Nutzer Eigentümer der Ressource ist
function checkOwnership(getResourceId) {
  return async (req, res, next) => {
    const resourceId = getResourceId(req);
    const resource = await db.orders.findById(resourceId);
    if (!resource) {
      return res.status(404).json({
        error: 'NOT_FOUND',
        message: 'Ressource nicht gefunden.'
      });
    }
    // Admins dürfen alles, andere nur eigene Ressourcen
    if (req.user.role !== 'admin' && resource.userId !== req.user.userId) {
      return res.status(403).json({
        error: 'FORBIDDEN',
        message: 'Sie dürfen nur auf eigene Ressourcen zugreifen.'
      });
    }
    req.resource = resource;
    next();
  };
}
// routes.js
// Anwendung der Middleware auf verschiedene Endpunkte

// Login: Authentifizierung -> JWT ausstellen
app.post('/api/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await db.users.findByEmail(email);
  if (!user || !await bcrypt.compare(password, user.passwordHash)) {
    return res.status(401).json({
      error: 'INVALID_CREDENTIALS',
      message: 'E-Mail oder Passwort falsch.'
    });
  }
  const token = jwt.sign(
    { userId: user.id, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: '15m' }
  );
  res.json({ token });
});

// Geschützte Routes: authenticate für alle, authorize für spezifische Rollen
app.get('/api/orders', authenticate, async (req, res) => {
  // Normale Nutzer sehen nur eigene Bestellungen
  if (req.user.role === 'admin') {
    const orders = await db.orders.findAll();
    res.json(orders);
  } else {
    const orders = await db.orders.findByUserId(req.user.userId);
    res.json(orders);
  }
});

app.get('/api/orders/:id', authenticate, checkOwnership(req => req.params.id), (req, res) => {
  res.json(req.resource);
});

app.post('/api/orders', authenticate, async (req, res) => {
  const order = await db.orders.create({
    ...req.body,
    userId: req.user.userId
  });
  res.status(201).json(order);
});

app.delete('/api/orders/:id', authenticate, authorize('admin'), checkOwnership(req => req.params.id), async (req, res) => {
  await db.orders.delete(req.params.id);
  res.status(204).send();
});

Detaillierte Informationen

Token-Lebensdauer und Refresh Tokens

Access Tokens sollten kurzlebig sein (15 Minuten). Refresh Tokens leben länger (Tage bis Wochen) und dienen nur dazu, neue Access Tokens zu holen. Wird ein Access Token kompromittiert, ist es nur kurz nutzbar. Wird ein Refresh Token kompromittiert, kann er serverseitig widerrufen werden.

JWT Struktur

Ein JWT besteht aus drei Base64-kodierten Teilen: Header, Payload, Signature. Der Header enthält Algorithmus und Typ. Der Payload enthält Claims wie sub (Subject), exp (Expiration), iat (Issued At), role, userId. Die Signature wird mit dem Secret oder Private Key berechnet.

Wichtig: Der Payload ist nur Base64-kodiert, nicht verschlüsselt. Niemals sensible Daten im JWT speichern. Die Sicherheit entsteht durch die Signatur — sie garantiert, dass der Token nicht manipuliert wurde.

Sicherheitsheader für REST APIs

HeaderZweck
Strict-Transport-SecurityErzwingt HTTPS
X-Content-Type-Options: nosniffVerhindert MIME-Sniffing
X-Frame-Options: DENYVerhindert Clickjacking
Cache-Control: no-storeVerhindert Caching sensibler Antworten
Access-Control-Allow-OriginCORS-Konfiguration

Häufige Schwachstellen (OWASP API Security Top 10)

  1. BOLA (Broken Object Level Authorization): Kein Ownership-Check
  2. Broken Authentication: Schwache Token-Erstellung, keine Rate Limits
  3. Excessive Data Exposure: API gibt mehr Felder zurück als nötig
  4. Lack of Resources & Rate Limiting: Keine Begrenzung der Anfragen
  5. Broken Function Level Authorization: Keine Rollenprüfung pro Endpunkt
  6. Mass Assignment: Ungefilterte Übernahme von Eingabefeldern
  7. Security Misconfiguration: Standard-Secrets, Debug-Modus, offene CORS

Best Practices Zusammenfassung

  • Verwende HTTPS immer und ausschließlich
  • Access Tokens kurzlebig (15 min), Refresh Tokens widerrufbar
  • RBAC für grobe Rechte, ABAC für feingranulare Policies
  • Ownership-Check bei jedem Endpunkt, der spezifische Ressourcen betrifft
  • Rate Limiting auf IP- und Token-Ebene
  • Input Validation mit Schema und Whitelisting
  • Keine sensiblen Daten im JWT-Payload
  • Sicherheitsheader setzen
  • Fehlermeldungen ohne interne Details
  • Regelmäßige Security-Audits und Penetration Tests

FAQ: REST API Sicherheit

1. Was ist der Unterschied zwischen Authentifizierung und Autorisierung?

Authentifizierung prüft die Identität eines Clients (Wer bist Du?), während Autorisierung prüft, ob der identifizierte Client die Berechtigung für eine bestimmte Aktion hat (Darfst Du das?). Authentifizierung erfolgt typischerweise durch Login mit Credentials, Autorisierung durch Rollen- oder Attributprüfung.

2. Was ist RBAC?

RBAC (Role-Based Access Control) ist ein Autorisierungsmodell, bei dem Benutzer Rollen zugewiesen werden und Rollen Berechtigungen haben. Die Zugriffskontrolle prüft, ob der Benutzer die erforderliche Rolle hat. Es ist einfach zu verstehen, kann aber bei feingranularen Berechtigungen zu Rollenexplosion führen.

3. Was ist ABAC?

ABAC (Attribute-Based Access Control) ist ein Autorisierungsmodell, bei dem die Zugriffskontrolle auf Attributen von Subjekt, Ressource, Aktion und Umgebung basiert. Policies definieren, welche Attributkombinationen welchen Zugriff erlauben. ABAC ist feingranularer als RBAC, aber komplexer zu implementieren.

4. Was ist Broken Object Level Authorization (BOLA)?

BOLA ist die häufigste API-Schwachstelle laut OWASP. Die API prüft zwar, ob der Nutzer authentifiziert ist, aber nicht, ob er auf die angefragte Ressource zugreifen darf. Ein Nutzer kann durch Ändern der ID in der URL auf fremde Daten zugreifen. Schutz: Ownership-Check bei jedem Endpunkt.

5. Warum sollten Access Tokens kurzlebig sein?

Access Tokens sollten kurzlebig sein (z.B. 15 Minuten), weil sie bei Kompromittierung nur kurz nutzbar sind. Längere Lebensdauer bedeutet höheres Risiko. Für längere Sessions werden Refresh Tokens verwendet, die serverseitig widerrufen werden können.

6. Was ist der Unterschied zwischen JWT und Session-Cookies?

JWT ist zustandslos (stateless) — der Server speichert keine Session, alle Informationen sind im Token enthalten. Session-Cookies erfordern einen serverseitigen Session-Store. JWT skaliert besser, ist aber schwerer zu widerrufen. Sessions sind einfacher zu invalidieren, benötigen aber Shared State bei mehreren Servern.

7. Was ist Mass Assignment und wie verhindert man es?

Mass Assignment entsteht, wenn der Server alle Eingabefelder ungeprüft übernimmt. Ein Client könnte ein Feld wie role: admin mitsenden und sich selbst Admin-Rechte geben. Schutz: Explizite Feldauswahl (Whitelisting), DTOs mit nur den erlaubten Feldern und Validierung der Eingaben.

8. Warum ist CORS wichtig für API-Sicherheit?

CORS (Cross-Origin Resource Sharing) regelt, welche fremden Origins aus dem Browser auf die API zugreifen dürfen. Ohne CORS-Konfiguration können entweder legitime Browser-Clients blockiert werden oder — bei zu offener Konfiguration — beliebige Websites auf die API zugreifen. Die korrekte Einstellung ist ein Allowlist spezifischer Origins.

9. Was ist CSRF und wie betrifft es REST APIs?

CSRF (Cross-Site Request Forgery) tritt auf, wenn ein Angreifer den Browser eines Nutzers dazu bringt, eine Anfrage an die API zu senden, wobei das Session-Cookie automatisch mitgesendet wird. Bei Token-basierter Authentifizierung im Authorization-Header ist CSRF kein Risiko, da der Browser den Header nicht automatisch sendet. Bei Cookie-basierter Auth sollten CSRF-Tokens und SameSite-Attribute verwendet werden.

10. Sind JWT-Payloads verschlüsselt?

Nein, der JWT-Payload ist nur Base64-kodiert, nicht verschlüsselt. Jeder, der das Token abfängt, kann den Payload lesen. Die Sicherheit entsteht durch die Signatur, die Manipulation verhindert. Für vertrauliche Inhalte muss JWE (JSON Web Encryption) verwendet werden.

11. Was ist der PKCE Flow bei OAuth 2.0?

PKCE (Proof Key for Code Exchange) erweitert den Authorization Code Flow für SPAs und mobile Apps, die kein Client Secret sicher speichern können. Der Client generiert einen Code Verifier und sendet dessen Hash (Code Challenge) an den Authorization Server. Beim Token-Austausch muss der Client den Original-Verifier senden, was Interception des Authorization Codes nutzlos macht.

12. Wie funktioniert Rate Limiting bei APIs?

Rate Limiting begrenzt die Anzahl der Anfragen pro Client in einem Zeitraum. Typische Verfahren sind Fixed Window (z.B. 100 Requests pro Minute), Sliding Window und Token Bucket. Die Begrenzung kann auf IP-Adresse, API-Key oder Token erfolgen. Bei Überschreitung antwortet der Server mit 429 Too Many Requests und einem Retry-After Header.

13. Welche HTTP-Statuscodes sind für Authentifizierungsfehler relevant?

401 Unauthorized bedeutet, dass die Authentifizierung fehlt oder ungültig ist. 403 Forbidden bedeutet, dass der Client authentifiziert ist, aber nicht die Berechtigung für die angefragte Aktion hat. 429 Too Many Requests zeigt an, dass zu viele Anfragen gesendet wurden.

14. Was ist das Principle of Least Privilege?

Das Principle of Least Privilege besagt, dass jeder Client und jeder Nutzer nur die minimalen Berechtigungen erhält, die für seine Aufgabe nötig sind. Ein Lesezugriff-Client bekommt kein Schreibrecht. Ein Redakteur bekommt keine Admin-Rechte. Dies reduziert die Angriffsfläche bei Kompromittierung.

15. Wie widerruft man ein JWT vor Ablauf?

Da JWT zustandslos ist, kann es nicht einfach widerrufen werden. Lösungen: Eine Revocation List (Blacklist) serverseitig pflegen und bei jeder Anfrage prüfen, oder kurze Token-Lebensdauer mit Refresh Tokens verwenden, die widerrufbar sind. Bei Logout kann der zugehörige Refresh Token invalidiert werden, sodass keine neuen Access Tokens mehr ausgestellt werden.

Weiter im API Lernpfad

Der nächste Artikel im API Lernpfad behandelt API Security Best Practices: APIs schützen, absichern und betreiben — die wichtigsten Sicherheitsmaßnahmen für den API-Betrieb nach OWASP und Best Practices.

Quellen und weitere Ressourcen

  1. https://owasp.org/API-Security/editions/2023/en/0x11-t10/
  2. https://datatracker.ietf.org/doc/html/rfc6749 (OAuth 2.0)
  3. https://datatracker.ietf.org/doc/html/rfc7519 (JWT)
  4. https://owasp.org/www-project-top-ten/
  5. https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html

Buchempfehlungen zur API-Entwicklung

API-Entwicklung

Bücher über API-Design, REST, GraphQL, OpenAPI und API-Architektur

REST und HTTP: Entwicklung und Integration nach REST-Prinzipien von Stefan Tilkov

REST und HTTP: Entwicklung und Integration nach REST-Prinzipien von Stefan Tilkov

Bei Amazon ansehen

Affiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.

API-Design: Praxishandbuch für Java- und Webservice-Entwickler

API-Design: Praxishandbuch für Java- und Webservice-Entwickler

Bei Amazon ansehen

Affiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.

Microservices: Grundlagen flexibler Softwarearchitekturen von Eberhard Wolff

Microservices: Grundlagen flexibler Softwarearchitekturen von Eberhard Wolff

Bei Amazon ansehen

Affiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.

Zurück zum DEV Blog
Share:

Ähnliche Beiträge