DE | EN

Security Headers Guide

All important HTTP security headers explained: HSTS, CSP, X-Frame-Options, and more. With example configurations for Apache and Nginx.

Why Are Security Headers Important?

HTTP security headers are one of the simplest and most effective methods to protect your website against common attacks. They are sent by the server as HTTP response headers and instruct the browser to enforce specific security policies.

Beyond direct security benefits, they also serve as a signal for Google: websites with HTTPS and proper security headers are considered more trustworthy. This can positively affect your rankings.

Strict-Transport-Security (HSTS)

HSTS enforces that the browser only accesses your website via HTTPS. This prevents man-in-the-middle attacks and SSL stripping.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • max-age: How long (in seconds) the browser should enforce HTTPS. 31536000 = 1 year.
  • includeSubDomains: Also applies to all subdomains.
  • preload: Enables inclusion in the browser preload list, so HTTPS is enforced from the very first visit.

Important: Only enable HSTS once you are sure your entire website works correctly over HTTPS. Rolling back is not straightforward.

Content-Security-Policy (CSP)

CSP is the most powerful security header. It defines which sources the browser is allowed to load resources from. This prevents Cross-Site Scripting (XSS) and data injection attacks.

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com; frame-ancestors 'none'
  • default-src: Default policy for all resource types.
  • script-src: Allowed sources for JavaScript. Avoid 'unsafe-inline' and 'unsafe-eval' when possible.
  • style-src: Allowed sources for CSS.
  • img-src: Allowed sources for images.
  • frame-ancestors: Prevents your page from being embedded in frames (replaces X-Frame-Options).

Tip: Start with Content-Security-Policy-Report-Only to log violations without blocking resources. This lets you gradually adjust the policy.

X-Frame-Options

Prevents clickjacking attacks by stopping the page from being embedded in an <iframe>.

X-Frame-Options: SAMEORIGIN
  • DENY: The page cannot be embedded anywhere.
  • SAMEORIGIN: Only pages from the same domain can embed the page.

Note: frame-ancestors in CSP is the modern alternative and offers more control.

X-Content-Type-Options

Prevents MIME type sniffing. The browser only accepts the declared Content-Type and does not try to guess the type on its own — which can be exploited in attacks.

X-Content-Type-Options: nosniff

This header has only one valid value and should be set on every website.

Referrer-Policy

Controls what referrer information is sent with navigation and requests. Protects your users' privacy.

Referrer-Policy: strict-origin-when-cross-origin
  • no-referrer: Never sends referrer information.
  • strict-origin-when-cross-origin: Sends the full referrer for same-origin requests, only the origin for cross-origin requests, and nothing on HTTP-to-HTTPS downgrade. A good compromise.
  • same-origin: Referrer only for same-origin requests.

Permissions-Policy

Controls which browser features and APIs your website is allowed to use. This prevents embedded third-party content from accessing sensitive APIs.

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(self)
  • camera=(): Camera access not allowed for anyone.
  • microphone=(): Microphone access disabled.
  • geolocation=(): Location queries disabled.
  • payment=(self): Payment API only for the page itself.

Example Configuration

Apache (.htaccess)

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; frame-ancestors 'none'"

Nginx

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" 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'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; frame-ancestors 'none'" always;

Testing Security Headers

After configuration, you should test your headers:

  • PageScore: Automatically checks all security headers and provides improvement suggestions.
  • Browser DevTools: Under Network → Response Headers you can inspect the sent headers.
  • curl: curl -I https://your-domain.com shows the response headers in the terminal.

Check your website's security headers now with PageScore — free and in seconds.