Vorhaben besprechen

Toolbox · Download

Security-Header-Spickzettel: empfohlene Werte und fertige Konfiguration

HTTP-Sicherheits-Header mit Zweck, empfohlenem Wert und Konfiguration für nginx, Apache, IIS und Next.js

Stand
22.10.2026
Online
tomoris.com/downloads/security-header-spickzettel
Für wen
  • Wer Webserver mit nginx, Apache oder IIS betreibt
  • Wer Websites und Webanwendungen entwickelt, etwa mit Next.js
  • IT-Verantwortliche, die Befunde aus Prüfberichten oder Pentests umsetzen lassen

Security-Header sind Anweisungen Ihres Webservers an den Browser. Sie kosten nichts und schließen ganze Angriffsklassen aus: Mitlesen über unverschlüsseltes HTTP, Clickjacking, eingeschleuste Skripte. Dieser Spickzettel nennt für jeden Header den empfohlenen Startwert, erklärt seinen Zweck und liefert die fertige Konfiguration für nginx, Apache, IIS und Next.js. Die Werte entsprechen den Empfehlungen des kostenlosen Security-Header-Checks von TOMORIS.

In vier Schritten einführen

  1. Bestand messen

    Prüfen Sie, welche Header Ihre Website heute sendet, zum Beispiel mit dem kostenlosen Security-Header-Check von TOMORIS unter tomoris.com/tools.

  2. Einfache Header zuerst

    Beginnen Sie mit X-Content-Type-Options, Referrer-Policy, X-Frame-Options, der Umleitung von HTTP auf HTTPS und dem Entfernen von Versionsangaben. Prüfen Sie vorher, ob fremde Websites Ihre Seiten absichtlich einbetten und ob alle Dateien mit korrektem Content-Type ausgeliefert werden.

  3. HSTS und CSP stufenweise

    HSTS mit kurzer Laufzeit beginnen und schrittweise erhöhen (hstspreload.org nennt die Stufen 5 Minuten, 1 Woche und 1 Monat), dann ein Jahr. Die CSP zuerst als Content-Security-Policy-Report-Only ausliefern und die gemeldeten Verstöße auswerten.

  4. Durchsetzen und wiederholen

    Dieselbe Richtlinie als Content-Security-Policy setzen und nach jeder größeren Änderung an der Website erneut prüfen.

Was weg sollte: Versionsangaben

Header wie Server: nginx/1.24.0 oder X-Powered-By: PHP/8.1.2 nennen Software und Version. OWASP führt sie in seiner Liste der Header, die nach Möglichkeit entfernt werden sollten, damit keine technischen Details preisgegeben werden.

  • nginx: server_tokens off; entfernt die Versionsnummer aus dem Server-Header und von Fehlerseiten. Der Header selbst bleibt.
  • Apache: ServerTokens Prod (nur in der Serverkonfiguration) sendet nur noch Server: Apache; ServerSignature Off ist bereits der Standard.
  • PHP: expose_php = Off in der php.ini entfernt den Header X-Powered-By mit der PHP-Version.
  • IIS: <remove name="X-Powered-By" /> in den customHeaders und removeServerHeader="true" in requestFiltering (ab IIS 10.0 Version 1709).
  • Next.js: poweredByHeader:false in der next.config.

Das Verbergen von Versionen ersetzt keine Updates. Auch die Apache-Dokumentation nennt Sicherheit durch Verschleierung einen Mythos. Es nimmt Angreifern aber eine bequeme Abkürzung.

Konfiguration für nginx

nginx: server-Block
server {
    listen 443 ssl;
    server_name example.com;
    server_tokens off;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests" always;
    add_header X-Frame-Options "SAMEORIGIN" 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=(), payment=(), usb=(), browsing-topics=()" always;
    add_header Cross-Origin-Opener-Policy "same-origin-allow-popups" always;
    add_header Cross-Origin-Resource-Policy "same-site" always;
}

# HTTP dauerhaft auf HTTPS umleiten
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
  • Ohne always setzt nginx die Header nur bei den Statuscodes 200, 201, 204, 206, 301, 302, 303, 304, 307 und 308, also nicht auf Fehlerseiten.
  • Vererbung: add_header-Direktiven gelten nur dann aus der übergeordneten Ebene, wenn auf der aktuellen Ebene kein eigenes add_header steht. Ein einziges add_header in einem location-Block lässt dort alle Security-Header der server-Ebene wegfallen.
  • Ab nginx 1.29.3 (stabil ab 1.30) übernimmt add_header_inherit merge; die Header der übergeordneten Ebene zusätzlich.

Konfiguration für Apache

Apache httpd 2.4
# VirtualHost für HTTPS oder .htaccess (mod_headers)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()"
Header always set Cross-Origin-Opener-Policy "same-origin-allow-popups"
Header always set Cross-Origin-Resource-Policy "same-site"
Header unset X-Powered-By

# nur in der Serverkonfiguration (httpd.conf), nicht in .htaccess
ServerTokens Prod
ServerSignature Off

# VirtualHost für Port 80: dauerhaft auf HTTPS umleiten
Redirect permanent / https://example.com/
  • always setzt die Header auch bei Fehlerantworten und nach internen Weiterleitungen, etwa durch ErrorDocument.
  • In einer .htaccess wirkt Header nur, wenn die Serverkonfiguration dort AllowOverride FileInfo erlaubt.
  • Redirect permanent antwortet mit Status 301.

Konfiguration für IIS

IIS: web.config
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By" />
        <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
        <add name="Content-Security-Policy" value="default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests" />
        <add name="X-Frame-Options" value="SAMEORIGIN" />
        <add name="X-Content-Type-Options" value="nosniff" />
        <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
        <add name="Permissions-Policy" value="camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()" />
        <add name="Cross-Origin-Opener-Policy" value="same-origin-allow-popups" />
        <add name="Cross-Origin-Resource-Policy" value="same-site" />
      </customHeaders>
    </httpProtocol>
    <security>
      <requestFiltering removeServerHeader="true" />
    </security>
  </system.webServer>
</configuration>
  • removeServerHeader gibt es ab IIS 10.0 und wirkt erst ab Windows Server bzw. Windows 10, jeweils Version 1709.
  • Für HSTS samt Umleitung von HTTP auf HTTPS kennt IIS ab 10.0 Version 1709 das Element <hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" /> je Site in der applicationHost.config, nicht in der web.config. Lassen Sie dann den customHeader für HSTS weg, damit der Header nicht doppelt gesendet wird.

Konfiguration für Next.js

Next.js: next.config.ts
import type {NextConfig} from 'next';

// Ohne Nonces braucht Next.js 'unsafe-inline' für Skripte und Styles
// (Next.js-Leitfaden „Content Security Policy“, Abschnitt „Without Nonces“)
const securityHeaders=[
  {key:'Strict-Transport-Security',value:"max-age=31536000; includeSubDomains"},
  {key:'Content-Security-Policy',value:"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data:; font-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests"},
  {key:'X-Frame-Options',value:"SAMEORIGIN"},
  {key:'X-Content-Type-Options',value:"nosniff"},
  {key:'Referrer-Policy',value:"strict-origin-when-cross-origin"},
  {key:'Permissions-Policy',value:"camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()"},
  {key:'Cross-Origin-Opener-Policy',value:"same-origin-allow-popups"},
  {key:'Cross-Origin-Resource-Policy',value:"same-site"},
];

const nextConfig:NextConfig={
  poweredByHeader:false,
  async headers(){
    return [{source:'/:path*',headers:securityHeaders}];
  },
};

export default nextConfig;
  • Ohne Nonces nennt der Next.js-Leitfaden 'unsafe-inline' für Skripte und Styles. Der Security-Header-Check wertet das als Hinweis, weil die CSP damit eingeschleuste Inline-Skripte nicht mehr blockiert.
  • Strenger geht es mit Nonces: Sie werden im Proxy erzeugt (proxy.ts, bis Next.js 15 Middleware). Dann müssen alle Seiten dynamisch gerendert werden; statische Optimierung und ISR entfallen.

Quellen

  1. OWASP Secure Headers Project: Best Practices und Liste empfohlener Header — Werte aus ci/headers_add.json, Stand 18.10.2026
    https://owasp.org/www-project-secure-headers/
  2. OWASP Secure Headers Project: zu entfernende Header (headers_remove.json)
    https://github.com/OWASP/secure-headers-project/blob/master/ci/headers_remove.json
  3. MDN: Strict-Transport-Security
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security
  4. MDN: Content-Security-Policy und Content-Security-Policy-Report-Only
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Content-Security-Policy-Report-Only
  5. MDN: X-Frame-Options
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/X-Frame-Options
  6. W3C Content Security Policy Level 3, Abschnitt 6.4.2.2 (frame-ancestors und X-Frame-Options)
    https://www.w3.org/TR/CSP3/
  7. MDN: X-Content-Type-Options
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options
  8. MDN: Referrer-Policy
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Referrer-Policy
  9. MDN: Permissions-Policy (und browsing-topics, veraltet)
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Permissions-Policy
  10. MDN: Cross-Origin-Opener-Policy
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Cross-Origin-Opener-Policy
  11. MDN: Cross-Origin-Resource-Policy
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Cross-Origin-Resource-Policy
  12. MDN: X-XSS-Protection
    https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/X-XSS-Protection
  13. nginx: Modul ngx_http_headers_module (add_header, always, add_header_inherit)
    https://nginx.org/en/docs/http/ngx_http_headers_module.html
  14. nginx: server_tokens
    https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
  15. Apache httpd 2.4: mod_headers
    https://httpd.apache.org/docs/2.4/mod/mod_headers.html
  16. Apache httpd 2.4: ServerTokens und ServerSignature
    https://httpd.apache.org/docs/2.4/mod/core.html#servertokens
  17. Apache httpd 2.4: mod_alias (Redirect permanent)
    https://httpd.apache.org/docs/2.4/mod/mod_alias.html
  18. PHP-Handbuch: expose_php
    https://www.php.net/manual/en/ini.core.php
  19. Microsoft Learn: IIS customHeaders
    https://learn.microsoft.com/iis/configuration/system.webserver/httpprotocol/customheaders/
  20. Microsoft Learn: IIS requestFiltering (removeServerHeader)
    https://learn.microsoft.com/iis/configuration/system.webserver/security/requestfiltering/
  21. Microsoft Learn: IIS HSTS je Site
    https://learn.microsoft.com/iis/configuration/system.applicationhost/sites/site/hsts
  22. hstspreload.org: Voraussetzungen und schrittweise Einführung von HSTS
    https://hstspreload.org/
  23. Next.js: headers in der next.config
    https://nextjs.org/docs/app/api-reference/config/next-config-js/headers
  24. Next.js: poweredByHeader
    https://nextjs.org/docs/app/api-reference/config/next-config-js/poweredByHeader
  25. Next.js: Leitfaden Content Security Policy (Nonces, Proxy, Without Nonces)
    https://nextjs.org/docs/app/guides/content-security-policy