Security-Header-Architektur für Astro

Implementierungsleitfaden: Alle Security Headers zentral über src/middleware.ts verwalten -- mit SSR, Hybrid-Modus und SSG-Hosting-Fallbacks.

Astro · Implementierung

Header-Architektur in Astro

In Astro haengt die Header-Strategie vom Output-Modus ab. Im SSR-Modus (output: 'server') laeuft src/middleware.ts bei jedem Request und kann alle Header dynamisch setzen -- inklusive CSP-Nonces. Im SSG-Modus (output: 'static') gibt es keine Middleware: Header müssen auf dem Webserver oder der Hosting-Plattform konfiguriert werden.

Der Hybrid-Modus (output: 'hybrid') kombiniert beides: Seiten mit export const prerender = true werden statisch generiert und verlieren Middleware-Header. Dynamische Seiten behalten die volle Middleware-Funktionalität. Wolf-Agents nutzt Astro im SSR-Modus mit zentraler Middleware für alle Security Headers.

1 Schritt 1 von 3

Zentrale Middleware mit allen Headern

Erstellen Sie src/middleware.ts mit defineMiddleware aus astro:middleware. Diese Datei wird automatisch bei jedem serverseitigen Request ausgeführt. Setzen Sie hier alle Security Headers an einer Stelle -- das vermeidet Duplikation und erleichtert die Wartung.

src/middleware.ts SSR
// src/middleware.ts -- Zentrale Security Headers
import { defineMiddleware } from 'astro:middleware';
import crypto from 'node:crypto';

export const onRequest = defineMiddleware(async (context, next) => {
  const nonce = crypto.randomUUID();
  context.locals.nonce = nonce;

  const response = await next();

  // Security Headers
  response.headers.set('X-Frame-Options', 'DENY');
  response.headers.set('X-Content-Type-Options', 'nosniff');
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  response.headers.set('Permissions-Policy',
    'camera=(), microphone=(), geolocation=(), payment=()');
  response.headers.set('Strict-Transport-Security',
    'max-age=31536000; includeSubDomains; preload');
  response.headers.set('Content-Security-Policy',
    `default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'`);

  return response;
});
astro.config.mjs Konfiguration
// astro.config.mjs -- SSR mit Node-Adapter
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
Warum defineMiddleware?

Die Middleware hat Zugriff auf context.locals, um Daten wie CSP-Nonces zwischen Header und Template zu teilen. Der Nonce wird einmal pro Request generiert und ist über Astro.locals.nonce in allen .astro-Templates verfügbar.

2 Schritt 2 von 3

SSG-Fallback: Header auf Server-Ebene

Für output: 'static' oder prerenderte Seiten im Hybrid-Modus müssen Sie Header auf dem Webserver oder der Hosting-Plattform setzen. Waehlen Sie die passende Konfiguration für Ihren Deployment-Anbieter.

nginx.conf Nginx
# Nginx -- Headers für SSG oder prerenderte Seiten
server {
    listen 443 ssl http2;
    server_name ihre-domain.de;

    # Security Headers (statisch)
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'" always;

    location / {
        root /var/www/astro-site/dist;
        try_files $uri $uri/index.html =404;
    }
}
vercel.json Vercel
// vercel.json -- Headers für Vercel-Deployments
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Frame-Options", "value": "DENY" },
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains; preload" },
        { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
      ]
    }
  ]
}
public/_headers Netlify
# public/_headers -- Netlify
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  Permissions-Policy: camera=(), microphone=(), geolocation=()
  Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'
3 Schritt 3 von 3

Verifizieren

Erstellen Sie einen Production-Build und prüfen Sie die Header. Der Wolf-Agents Web Security Check analysiert alle gesetzten Header -- inklusive CSP-Nonces, HSTS-Preload und Permissions-Policy.

Terminal Verifizieren
# Production-Build und Header prüfen
npm run build
node dist/server/entry.mjs

curl -sI https://ihre-domain.de | grep -iE "x-frame|x-content|referrer|strict-transport|permissions|content-security"

# Erwartete Ausgabe:
# X-Frame-Options: DENY
# X-Content-Type-Options: nosniff
# Referrer-Policy: strict-origin-when-cross-origin
# Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
# Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-...' 'strict-dynamic'; ...

Häufige Fehler bei der Astro-Architektur

Middleware laeuft nicht im SSG-Modus

src/middleware.ts wird nur bei output: 'server' oder output: 'hybrid' ausgeführt. Bei output: 'static' existiert kein Server -- Header müssen auf Hosting-Ebene gesetzt werden.

prerender=true verliert Middleware-Header

Seiten mit export const prerender = true werden zur Build-Zeit gerendert. Die Middleware laeuft nicht für diese Seiten. Setzen Sie Header für prerenderte Seiten über die Server-Konfiguration.

astro.config.mjs hat kein headers-Feld

Im Gegensatz zu Next.js oder Nuxt gibt es in Astro kein headers-Feld in der Config. Verwenden Sie ausschließlich die Middleware oder Hosting-Konfigurationen.

Adapter-Inkompatibilitaet

Nicht alle Adapter unterstützen response.headers.set() identisch. Testen Sie immer mit dem finalen Adapter -- insbesondere bei Cloudflare Workers, wo einige Header-Manipulationen eingeschraenkt sind.

Compliance-Relevanz

Eine konsolidierte Header-Architektur ist die Grundlage für alle weiteren Security-Maßnahmen. NIS2 fordert technische Cybersicherheitsmassnahmen -- eine zentrale Middleware stellt sicher, dass kein Header vergessen wird. PCI DSS 4.0 verlangt die Kontrolle aller geladenen Scripts. Der Wolf-Agents Web Security Check bewertet 166 Prüfpunkte und zeigt lückenlos, welche Header gesetzt sind.

Wie steht Ihre Domain bei Implementierungs-Architektur?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.