Cozmo Scan My SEO Logo

Missing Security Headers: Everything You Need to Know and How to Fix Them


Run a Crawl Now

Missing Security Headers: What the Finding Actually Means

A missing security header means a response did not include a browser instruction that could reduce a particular risk. It does not automatically mean the page is compromised, and it does not mean every possible security header belongs on every response. The right fix depends on what the page does, how it is hosted, whether it must be framed or open pop-up windows, which third-party resources it loads, and whether every relevant hostname already supports HTTPS.

ScanMySEO can flag crawled responses where expected security headers are missing so that you know where to investigate. Treat the finding as a starting point: confirm the exact response, choose a policy that fits the site, deploy it in the correct layer, and test the result. A header being present is not proof that its value is secure, and a scanner grade is not a substitute for application-security review.

Fix security headers for their security and privacy value, not as a shortcut to higher rankings. Google documents HTTPS as a search and page-experience consideration, but it does not present Content Security Policy, X-Frame-Options or the other headers in this guide as a direct ranking checklist. Security incidents can still damage availability, content integrity and visitor trust, so the work matters even without a promised SEO uplift. See Google’s current page-experience guidance for that distinction.

Missing Security Headers: The Two-Minute Decision

Use this order rather than copying a large “perfect header set” into production:

  1. Make HTTPS reliable first. Confirm the certificate, redirects, mixed content, apex domain, www hostname and relevant subdomains before considering HTTP Strict Transport Security (HSTS).
  2. Add the lower-risk baseline. X-Content-Type-Options: nosniff and an explicit Referrer-Policy are usually simpler to deploy, provided your server already sends correct content types.
  3. Prevent unwanted framing. Use Content Security Policy (CSP) frame-ancestors; add a matching X-Frame-Options value when legacy compatibility is useful.
  4. Stage HSTS. Start with a short max-age, monitor, then increase it. Do not add includeSubDomains or preload until you understand the long-term effect.
  5. Design CSP rather than guessing it. Test a proposed policy in report-only mode, inspect violations, then enforce it gradually. A copied CSP can disable analytics, forms, payment widgets, maps, fonts, images or your own JavaScript.
  6. Treat advanced headers as conditional. Permissions Policy and cross-origin isolation headers can be valuable, but they are not universal requirements and may break legitimate features.

For a brochure site, the owner, host or developer may be able to complete the lower-risk fixes. For sites with logins, payments, user-generated content, sensitive data or substantial custom JavaScript, involve a developer or qualified security specialist before enforcing HSTS or a strict CSP.

What the Main Security Headers Defend Against

Strict-Transport-Security (HSTS)

HSTS tells a browser that future connections to a host must use HTTPS. It helps resist protocol-downgrade attacks and prevents users from clicking through certificate errors after the browser has learned the policy. The header is only trusted when received over HTTPS; browsers ignore it on an HTTP response. HSTS also does not repair an invalid certificate, mixed content or an HTTPS-incompatible subdomain. Read the MDN HSTS reference before deployment.

Key risk: a long max-age, includeSubDomains or preloading can make a hostname inaccessible when HTTPS later fails. Current HSTS preload guidance recommends ramping up in stages and says preloading should not be enabled by default.

Content-Security-Policy (CSP)

CSP limits what a document may load or execute. A strong policy can provide defence in depth against cross-site scripting (XSS), restrict framing and upgrade insecure resource requests. It does not remove vulnerabilities from the application and does not replace output encoding, input handling or sanitisation. Modern strict CSPs commonly use per-response nonces or hashes for scripts rather than broad domain allowlists. The MDN CSP implementation guide explains this approach.

Key risk: an enforced policy that is too restrictive can break the page; a policy that relies on 'unsafe-inline', overly broad sources or a long list of trusted domains may provide much less protection than its presence suggests. Test with Content-Security-Policy-Report-Only first, then move a reviewed policy into enforcement.

CSP frame-ancestors and X-Frame-Options

These controls reduce clickjacking risk by deciding who may embed your page. Use frame-ancestors 'none' when a page must never be framed, or frame-ancestors 'self' when same-origin framing is required. The directive does not inherit from default-src, so it must be stated explicitly. It must also be sent as an HTTP response header; putting frame-ancestors or X-Frame-Options in a meta element does not provide equivalent framing protection.

X-Frame-Options: DENY and SAMEORIGIN remain useful compatibility options, but ALLOW-FROM is obsolete. CSP frame-ancestors is more flexible when specific external origins genuinely need to frame a page. Keep the two headers consistent when you send both. See the MDN framing guidance.

X-Content-Type-Options

X-Content-Type-Options: nosniff tells browsers to respect the declared Content-Type instead of guessing a different type. This can reduce MIME-confusion attacks, including cases where untrusted content could otherwise be interpreted as executable HTML or script. It works alongside correct media types; it does not compensate for a server that labels files incorrectly. The MDN nosniff reference covers the behaviour.

Referrer-Policy

Referrer-Policy controls how much of the current URL is sent when the browser requests another resource or follows a link. Modern browsers default to strict-origin-when-cross-origin, which sends the full referrer on same-origin requests, only the origin on secure cross-origin requests, and nothing when moving from HTTPS to a less secure destination. Sending an explicit policy still records your intended privacy behaviour and helps older clients behave consistently. A stricter value may be appropriate when URLs contain sensitive information, but it can reduce referral detail used by analytics or partners. See the MDN Referrer-Policy reference.

Permissions Policy and cross-origin isolation

Permissions-Policy can disable browser features such as camera, microphone or geolocation where the site does not need them. Browser support and directive behaviour still vary, so test the exact features you restrict. Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy can provide stronger isolation for suitable applications, but may affect embedded media, third-party resources, authentication pop-ups and integrations. These are deliberate architecture choices, not automatic fixes for every marketing site or API.

Which Missing Header Findings Should You Prioritise?

Fix or investigate first

  • HTTPS or certificate failures: repair these before HSTS. A strict transport policy cannot rescue a broken secure connection.
  • Interactive pages that anyone can frame: add appropriate frame-ancestors protection, particularly around sign-in, account, checkout and administrative actions.
  • Incorrect content types or user-uploaded files: fix Content-Type and add nosniff; the combination matters.
  • Applications exposed to script injection risk: plan a CSP with the development team. The value can be high, but so is the need for careful implementation.
  • Sensitive responses cached too broadly: review Cache-Control and cookie attributes as part of the wider security review. These are route-specific controls rather than one universal site-wide value.

Plan, test and roll out

  • HSTS: deploy only after HTTPS coverage is proven, then increase max-age gradually.
  • Full CSP: begin in report-only mode, separate genuine violations from expected third-party activity, and enforce a reviewed policy.
  • Permissions Policy: disable features the site does not need, but verify browser support and embedded content.
  • Cross-origin isolation: use it when the application needs the isolation model and the team can test every integration.

Do not add obsolete headers just to satisfy an old checklist

  • X-XSS-Protection: deprecated and not a replacement for CSP; some current guidance recommends disabling the old browser filter with X-XSS-Protection: 0.
  • Public-Key-Pins (HPKP): obsolete and capable of locking site owners out when misconfigured.
  • Expect-CT: largely obsolete because mainstream certificate-transparency enforcement moved elsewhere.
  • Feature-Policy: superseded by Permissions-Policy, with different syntax and incomplete cross-browser support.

A scanner may still report some of these names because of legacy rules or a specific compatibility profile. Check what the finding actually tests before adding a header that modern browsers no longer need.

How to Diagnose and Fix Missing Security Headers

  1. Inspect the exact response that was flagged
    • Open browser Developer Tools, load the page, select the main document in the Network panel, then review Response Headers.
    • From a terminal, curl -I https://example.com/ is a quick check, but some servers treat HEAD differently from a normal GET; confirm in the browser when results disagree.
    • Check the final HTTPS page, the HTTP-to-HTTPS redirect, apex and www hosts, important subdomains, a 404 page, login or checkout routes, and any page type that uses a different application or CDN rule.
  2. Identify which layer owns the response
    • Headers may come from the application framework, Apache or NGINX, a reverse proxy, a managed host, a web application firewall or a CDN.
    • Choose one clear source of truth where possible. Duplicate or conflicting policies make troubleshooting harder and may produce a stricter effective CSP than expected.
    • Record the current values and have a rollback method before changing a site-wide rule.
  3. Start with lower-risk controls
    • Correct every response’s Content-Type, then add X-Content-Type-Options: nosniff.
    • Set an explicit referrer policy such as strict-origin-when-cross-origin, or choose a stricter value when the privacy trade-off is understood.
    • For pages that should not be embedded, add Content-Security-Policy: frame-ancestors 'none'. Use 'self' when same-origin framing is necessary.
    • Optionally send a matching X-Frame-Options value for compatibility with older clients.
  4. Stage HSTS instead of copying a two-year value
    • Verify that HTTPS works on every hostname the policy could affect.
    • Send HSTS on HTTPS responses only. Begin with a short max-age, such as 300 seconds, then progress through longer test periods after monitoring.
    • Add includeSubDomains only when all present and future subdomains can remain on HTTPS.
    • Do not add preload by default. Submission can affect every subdomain and removal may take months to reach browsers.
  5. Build CSP from the site’s real resource inventory
    • List the scripts, styles, fonts, images, frames, form destinations and network connections the page genuinely needs.
    • Start with Content-Security-Policy-Report-Only so violations are visible without blocking resources.
    • Review browser-console messages and, for larger sites, send reports to a controlled reporting endpoint. Google Search Console and ordinary analytics do not provide a CSP violation log.
    • Prefer nonces or hashes for scripts where the application can support them. Avoid solving every violation by adding 'unsafe-inline', wildcards or entire third-party domains.
    • Move a stable policy into the enforced Content-Security-Policy header and continue monitoring.
  6. Verify functionality, not just header presence
    • Test navigation, forms, authentication, checkout, analytics, consent controls, maps, video, chat, fonts, downloads and embedded widgets.
    • Check desktop and mobile browsers, logged-in and logged-out states, cached and uncached responses, redirects and error pages.
    • Re-run the audit, but investigate any remaining finding at response level rather than assuming the deployment failed.

Configuration Examples for Apache, NGINX and Managed Platforms

These snippets illustrate where headers can be set; they are not a universal policy. Confirm that your site does not need external framing, object embeds or a different referrer policy before using the values. Deploy HSTS separately and only after completing the HTTPS checks above.

Apache with mod_headers

<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Content-Security-Policy "frame-ancestors 'self'"
  Header always set X-Frame-Options "SAMEORIGIN"
</IfModule>

For an initial HSTS test on a fully HTTPS host:

Header always set Strict-Transport-Security "max-age=300"

Apache’s mod_headers documentation explains the Header directive and the difference between normal and always processing.

NGINX

add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;

For an initial HSTS test on a fully HTTPS server block:

add_header Strict-Transport-Security "max-age=300" always;

Retest nested location blocks. NGINX header inheritance can change when a lower level defines its own add_header directives, and newer NGINX versions add explicit inheritance controls. Check the official NGINX header module documentation for the version you run.

Managed hosting, WordPress and CDNs

  • Prefer the host’s documented response-header feature or a server-level configuration over stacking several plugins that may overwrite one another.
  • When a CDN adds the header, verify the public edge response rather than only the origin. Cached pages and error responses may follow different rules.
  • Cloudflare users can add or modify public response headers with Response Header Transform Rules; confirm plan availability and rule order in current Cloudflare documentation.
  • For framework middleware, use the framework’s official security-header component where possible, then verify the final response after proxies and CDNs have processed it.

Worked Example: Hardening a Small Business Site Without Breaking It

Hypothetical example: a small appointment-booking site uses analytics, a consent manager, an embedded map and a third-party booking widget. An audit reports no HSTS, no CSP, no anti-framing header, no nosniff and no explicit referrer policy.

The owner does not paste a generic “A+ security header” block into production. Instead, the developer:

  1. confirms that the apex domain and www redirect correctly to HTTPS, but discovers a legacy subdomain that still lacks a valid certificate;
  2. adds correct content types, nosniff and strict-origin-when-cross-origin first;
  3. sets frame-ancestors 'self' and X-Frame-Options: SAMEORIGIN because nobody outside the site needs to embed its pages;
  4. starts HSTS with a short max-age but deliberately omits includeSubDomains until the legacy subdomain is migrated;
  5. tests a CSP in report-only mode and learns that the map, booking widget and consent manager require deliberate rules;
  6. works through those reports, uses a nonce for the site’s own scripts, and enforces the policy only after the booking journey passes testing.

The result is not “perfect security” or a guaranteed ranking increase. It is a defensible, tested set of browser controls that addresses the audit findings without disabling the functions customers need. That is the standard a useful fix should meet.

How to Verify the Fix and Troubleshoot a Failed Re-scan

If a re-scan still reports a missing header, work through the response path before changing the policy again:

  • Wrong protocol: HSTS is expected on the HTTPS response, not the insecure HTTP response.
  • Wrong hop: the header may exist on the origin but be removed, replaced or cached differently by a proxy or CDN.
  • Wrong status code: a rule may cover successful pages but not redirects, 404s or server errors. Apache and NGINX need configuration that applies to the intended responses.
  • Wrong page type: a separate application, subdomain, API or static-file service may send its own headers.
  • Report-only confusion: Content-Security-Policy-Report-Only is intentionally not an enforced CSP, so a scanner may still flag the absence of Content-Security-Policy.
  • Meta-element limitation: HSTS and X-Frame-Options cannot be implemented with a meta element, and CSP meta delivery does not support every directive, including framing protection.
  • Stale cache: purge the relevant CDN cache or wait for the cached response to expire, then inspect the response again.
  • Lowercase names: header names appearing in lowercase in HTTP/2 or HTTP/3 developer tools is normal; names are case-insensitive.

Verify with more than one method. Browser Developer Tools shows the response the user received; ScanMySEO can compare header coverage across crawled pages; and the MDN HTTP Observatory provides a focused security-header assessment. Automated scores are useful prompts, but the final decision should consider the page’s actual function and threat model.

Quick Reference: A Safer Implementation Order

Deployment checklist

  • Confirm valid HTTPS, redirects and certificates on every relevant hostname.
  • Inspect the exact public response, including CDN and proxy behaviour.
  • Set correct Content-Type values and add X-Content-Type-Options: nosniff.
  • Choose and document a Referrer-Policy.
  • Add CSP frame-ancestors; use a consistent X-Frame-Options fallback when appropriate.
  • Ramp up HSTS slowly; add includeSubDomains only after every subdomain is ready.
  • Do not enable HSTS preload by default.
  • Test CSP in report-only mode, then enforce a reviewed policy.
  • Treat Permissions Policy and cross-origin isolation as context-dependent.
  • Do not resurrect obsolete headers to satisfy an old checklist.
  • Test user journeys, redirects, errors, cached pages and multiple browsers.
  • Re-scan and investigate any remaining discrepancy at response level.

Authoritative resources

Security headers are browser-side layers, not a complete security programme. Start with the controls that fit the site, stage the changes that can lock users out or block resources, verify real user journeys, and bring in specialist review when the application handles sensitive actions or data.

Ready to Get More Out of ScanMySEO?

Whether you're just getting started or already have scans to review, take the next step towards boosting your search presence.

Register for Free
Hansel McKoy

Hey there, I'm Hansel, the founder of ScanMySEO. I've spent over ten years helping global brands boost their digital presence through technical SEO and growth marketing. With ScanMySEO, I've made it easy for anyone to perform powerful, AI-driven SEO audits and get actionable insights quickly. I'm passionate about making SEO accessible and effective for everyone. Thanks for checking out this article!

Hansel McKoy

Founder, ScanMySEO


Get More Out of ScanMySEO