Back to scan results
Check 3 of 45

HTTP Security Headers

We send a normal HTTP GET to your homepage and inspect the response headers for the modern set of browser-side security directives. Missing headers don't break your site, but they leave specific attack classes wide open.

What this check probes

  • Strict-Transport-Security (HSTS) — the check requires a valid positive max-age on successful HTTPS HTML pages served by a hostname. A year and includeSubDomains are recommendations, not minimum pass requirements. HSTS is not required on HTTP responses or IP literals.
  • X-Content-Type-Options: nosniff — stops browsers from MIME-sniffing a response and reinterpreting it (e.g., reading text/plain as JavaScript).
  • X-Frame-Options or Content-Security-Policy: frame-ancestors — clickjacking protection is assessed separately in Check 13.
  • Content-Security-Policy (CSP) — allow-list of script/style/image sources. The single most effective XSS mitigation when configured correctly.
  • Referrer-Policy — controls how much URL data leaks via the Referer header. Best practice: strict-origin-when-cross-origin.
  • Permissions-Policy is additional hardening advice, not part of this check's verdict. The obsolete X-XSS-Protection header is not required.

A missing or invalid nosniff or applicable HSTS header on a successful public HTML response is an ASV-readiness failure only after an independent repeat. Challenges, denied requests, API responses and error pages are not failed merely for missing browser headers. Missing CSP or Referrer-Policy remains an orange recommendation.

Why this matters for PCI DSS

PCI DSS 4.0 Requirement 6.2.4 requires protection against "common software attacks" — explicitly naming injection, broken access control, and request forgery. Browser security headers are the cheapest and most reliable defense against the client-side half of those attacks.

HSTS tells a browser that has received the policy over HTTPS to use HTTPS for later visits. It does not by itself protect a first-ever HTTP visit; preload is a separate deployment decision. Header findings can affect an ASV result, but this check is not an ASV attestation.

How to fix it

nginx — add to your server block:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self';" always;

Apache — in your VirtualHost (requires mod_headers):

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
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 Content-Security-Policy "default-src 'self'; ..."

IIS / web.config:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
      <add name="X-Content-Type-Options" value="nosniff" />
      <add name="X-Frame-Options" value="SAMEORIGIN" />
      <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Roll out CSP carefully — start in Content-Security-Policy-Report-Only mode and use the report endpoint to find legitimate inline scripts before enforcing. The Google CSP Evaluator grades your policy.

Verify the full set with securityheaders.com — aim for grade A.

Fixed it? Re-run the scan to confirm.

Run scan again