Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Web-Sicherheit Glossar

HTTP Security Headers

HTTP Security Headers sind Response-Header die der Webserver mit jeder Antwort sendet und dem Browser mitteilen wie er sich sicher verhalten soll - welche Ressourcen er laden darf, ob Seiten in Frames eingebettet werden können, ob Cookies nur über HTTPS gesendet werden. Sie sind einfach zu implementieren und schützen gegen eine Reihe von Angriffen.

HTTP Security Headers sind einer der einfachsten Sicherheitsgewinne in der Webentwicklung: Wenige Zeilen Konfiguration im Webserver oder Code schützen gegen XSS, Clickjacking, MIME-Type-Sniffing und erzwingen HTTPS. Trotzdem fehlen sie auf erschreckend vielen produktiven Webseiten - sie kosten nichts, schützen aber erheblich.

Die wichtigsten Security Headers

Content-Security-Policy (CSP) - Schutz gegen XSS:

  Content-Security-Policy:
    default-src 'self';
    script-src 'self' 'nonce-{RANDOM_PER_REQUEST}';
    style-src 'self' 'unsafe-inline';
    img-src 'self' data: https:;
    font-src 'self' https://fonts.gstatic.com;
    connect-src 'self' https://api.firma.de;
    frame-ancestors 'none';
    base-uri 'self';
    form-action 'self';
    upgrade-insecure-requests;

  Erklärung:
    default-src 'self'        → Nur von eigener Origin laden
    script-src nonce          → Scripts brauchen per-request Nonce
    frame-ancestors 'none'    → Clickjacking-Schutz (wie X-Frame-Options)
    upgrade-insecure-requests → HTTP-Links werden zu HTTPS
    base-uri 'self'           → base-Tag-Injection verhindern

  Einstieg: Report-Only-Modus:
    Content-Security-Policy-Report-Only:
      default-src 'self'; report-uri /csp-report
    → Keine Blockierung, nur Reports → gut zum Testen!

---

Strict-Transport-Security (HSTS) - HTTPS erzwingen:

  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

  max-age=31536000   → 1 Jahr HTTPS-Pflicht gespeichert im Browser
  includeSubDomains  → Gilt auch für alle Subdomains
  preload            → Eintragung in Browser-Preload-Liste

  HSTS Preload: hstspreload.org
  → Browser kommt nie mit HTTP an - verhindert SSL-Stripping!
  → Vorsicht: includeSubDomains erst wenn ALLE Subdomains HTTPS haben!

---

X-Frame-Options - Clickjacking-Schutz:

  X-Frame-Options: DENY
  → Seite darf nirgends in iframe eingebettet werden

  X-Frame-Options: SAMEORIGIN
  → Nur von eigener Domain einbettbar

  Hinweis: CSP frame-ancestors ist moderner und flexibler!
  Beide setzen für maximale Browser-Kompatibilität.

---

X-Content-Type-Options - MIME-Sniffing verhindern:

  X-Content-Type-Options: nosniff

  Verhindert: Browser rät MIME-Type auch wenn Server falsch deklariert
  → HTML-Datei als text/plain → Browser würde nicht als HTML ausführen
  → Angriff: Bild hochladen das eigentlich JavaScript ist

---

Referrer-Policy - Referrer-Informationen kontrollieren:

  Referrer-Policy: strict-origin-when-cross-origin

  Optionen:
  no-referrer                   → Kein Referrer-Header gesendet
  no-referrer-when-downgrade    → Kein Referrer bei HTTP→HTTP
  origin                        → Nur Origin (keine Pfade!)
  strict-origin-when-cross-origin → Origin bei Cross-Site, voll bei Same-Site

  Problem ohne Policy:
  User ist auf https://intern.firma.de/geheimprojekt
  → Klickt auf externen Link
  → Referrer: https://intern.firma.de/geheimprojekt → External site sieht URL!

---

Permissions-Policy - Browser-Features steuern:

  Permissions-Policy:
    camera=(),
    microphone=(),
    geolocation=(),
    payment=(),
    usb=()

  → Deaktiviert Zugriff auf Kamera, Mikrofon, GPS, Payment-API für eingebettete Inhalte
  → Früher: Feature-Policy Header

---

Cross-Origin Headers (CORS richtig konfigurieren):

  Access-Control-Allow-Origin: https://app.firma.de
  → NICHT: * (wenn Credentials gesendet werden!)

  Access-Control-Allow-Credentials: true
  → Nur wenn wirklich Cookies/Auth gebraucht werden!

  Access-Control-Allow-Methods: GET, POST, PUT, DELETE
  Access-Control-Allow-Headers: Content-Type, Authorization

  Gefährliche Fehlkonfiguration:
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Credentials: true
  → INVALID! Browser ignoriert das - aber manche Bibliotheken nicht!

Implementierung im Webserver und Code

nginx:
  server {
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    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 Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; upgrade-insecure-requests;" always;
    # "always" → auch bei 4xx/5xx Responses senden!
  }

---

Apache:
  <IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Frame-Options "DENY"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
  </IfModule>

---

Express.js (Node.js) mit Helmet:
  import helmet from 'helmet';

  app.use(helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", "data:", "https:"],
        frameAncestors: ["'none'"],
        upgradeInsecureRequests: [],
      }
    },
    hsts: {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true,
    },
    frameguard: { action: 'deny' },
    noSniff: true,
    referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
  }));

---

Astro.js (SSG/SSR):
  // astro.config.mjs:
  export default defineConfig({
    server: {
      headers: {
        'X-Frame-Options': 'DENY',
        'X-Content-Type-Options': 'nosniff',
        'Referrer-Policy': 'strict-origin-when-cross-origin',
      }
    }
  });

Security Header Testing

Online-Tools:
  → securityheaders.com: Report für jede URL
  → Mozilla Observatory (observatory.mozilla.org): A-F Score
  → HSTS Preload Check: hstspreload.org

Lokale Tests:
  # curl-Prüfung:
  curl -I https://yoursite.de | grep -i "content-security\|x-frame\|strict-transport\|x-content\|referrer"

  # nikto (HTTP Header Check):
  nikto -h https://yoursite.de -Plugins headers

Scoring:
  Mozilla Observatory Score:
  A+ (100/100): Alle wichtigen Header gesetzt, CSP strikt
  B  (55-74):   Meiste Header, CSP vorhanden aber locker
  D  (<40):     Fehlende HSTS oder CSP

  Ziel: A oder A+ bei Mozilla Observatory

Typische Findings im Pentest (fehlende Header):
  □ Kein HSTS → SSL-Stripping möglich
  □ Kein X-Frame-Options → Clickjacking möglich
  □ Kein X-Content-Type-Options → MIME-Sniffing
  □ Kein CSP → XSS ohne Mitigation
  □ Weites CORS (*) → Cross-Origin-Zugriff
  □ Server-Header zeigt Version: "Server: Apache/2.4.51"
    → Versions-Disclosure entfernen: ServerTokens Prod (Apache)

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung