Kodokon kodokon.com

Eine API in der Produktion absichern

Härte eine Node-API für die Produktion: korrektes CORS, Rate Limiting, Security-Header und Abwehr gegen die wichtigsten OWASP-API-Risiken.

11 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

OWASP pflegt eine Top 10 speziell für APIs. Die drei dominierenden Risiken: BOLA (Broken Object Level Authorization - auf das Objekt einer anderen Person zugreifen, indem man eine id ändert), Broken Authentication (schlecht geprüfte Tokens, schwache Secrets) und Unrestricted Resource Consumption (keine Grenze für Rate, Größe oder Dauer). Beachte, dass keines der drei durch die Installation einer Bibliothek behoben wird: Sie sind Eigenschaften deines Entwurfs. Beginnen wir mit den übergreifenden Mechanismen: CORS, Rate Limiting und Header.

JAVASCRIPT
import { createServer } from "node:http";

const allowed = new Set(["https://app.example.com"]);

const server = createServer((req, res) => {
  const origin = req.headers.origin;
  if (origin && allowed.has(origin)) {
    res.setHeader(
      "Access-Control-Allow-Origin",
      origin,
    );
    res.setHeader("Vary", "Origin");
  }
  if (req.method === "OPTIONS") {
    res.setHeader(
      "Access-Control-Allow-Methods",
      "GET,POST,PUT,DELETE",
    );
    res.setHeader(
      "Access-Control-Allow-Headers",
      "content-type,authorization",
    );
    res.setHeader("Access-Control-Max-Age", "86400");
    res.writeHead(204).end();
    return;
  }
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify({ ok: true }));
});

server.listen(3000);
CORS von Hand: Allowlist und Preflight.

Mach dir klar, was CORS nicht ist: ein Schutz für den Server. curl oder ein fremdes Backend ignorieren diese Header vollständig; nur der Browser setzt sie durch, um seine Nutzerinnen und Nutzer zu schützen. Drei Expertenregeln: Gib den exakten Origin aus einer Allowlist zurück (spiegle niemals blind den Header Origin), ergänze Vary: Origin, um Zwischen-Caches nicht zu vergiften, und wisse, dass der Platzhalter * von Browsern abgelehnt wird, sobald die Anfrage Cookies mitführt (credentials).

JAVASCRIPT
const WINDOW_MS = 60_000;
const LIMIT = 100;
const hits = new Map();

function check(ip) {
  const now = Date.now();
  const entry = hits.get(ip);
  if (!entry || now - entry.start >= WINDOW_MS) {
    hits.set(ip, { start: now, count: 1 });
    return { ok: true, remaining: LIMIT - 1 };
  }
  entry.count += 1;
  const remaining = Math.max(LIMIT - entry.count, 0);
  return { ok: entry.count <= LIMIT, remaining };
}

console.log(check("203.0.113.7"));
Festes Zeitfenster im Speicher: 429 zurückgeben, wenn ok false ist.

Security-Header kosten ein paar Zeilen und blockieren ganze Angriffsklassen: HSTS erzwingt HTTPS für künftige Besuche, X-Content-Type-Options: nosniff hindert den Browser daran, einen MIME-Typ zu erraten, und eine restriktive CSP (default-src 'none') macht die Ausnutzung einer versehentlich im Browser gerenderten API-Antwort unschädlich. Entferne außerdem jeden Header, der deinen Stack verrät: Express fügt standardmäßig X-Powered-By hinzu - schalte ihn mit app.disable('x-powered-by') ab.

JAVASCRIPT
function setSecurityHeaders(res) {
  res.setHeader(
    "Strict-Transport-Security",
    "max-age=63072000; includeSubDomains",
  );
  res.setHeader("X-Content-Type-Options", "nosniff");
  res.setHeader(
    "Content-Security-Policy",
    "default-src 'none'; frame-ancestors 'none'",
  );
  res.setHeader("Cache-Control", "no-store");
}

export { setSecurityHeaders };
Bei jeder API-Antwort aufzurufen.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Was schützt der CORS-Mechanismus tatsächlich?
    • Den Server vor automatisierten Anfragen (curl, Skripte)
    • Die Nutzerin oder den Nutzer des Browsers vor unerlaubten Cross-Origin-Zugriffen
    • Die API vor Denial-of-Service-Angriffen
  2. Warum ist Access-Control-Allow-Origin: * mit Anfragen unvereinbar, die Cookies senden?
    • Browser lehnen diese Kombination ab, um authentifizierte Sessions nicht jeder Website preiszugeben
    • Der Server gibt automatisch einen Fehler 500 zurück
    • Der Platzhalter deaktiviert die Cookies auf dem Server
  3. Eine authentifizierte API gibt GET /invoices/42 an eine Person zurück, der diese Rechnung nicht gehört. Um welches OWASP-API-Risiko handelt es sich?
    • Injection
    • Broken Object Level Authorization (BOLA)
    • Security Misconfiguration
    • Server-Side Request Forgery