Missing Security Headers: Everything You Need to Know and How to Fix Them
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:
- Make HTTPS reliable first. Confirm the certificate, redirects, mixed content, apex domain,
wwwhostname and relevant subdomains before considering HTTP Strict Transport Security (HSTS). - Add the lower-risk baseline.
X-Content-Type-Options: nosniffand an explicitReferrer-Policyare usually simpler to deploy, provided your server already sends correct content types. - Prevent unwanted framing. Use Content Security Policy (CSP)
frame-ancestors; add a matchingX-Frame-Optionsvalue when legacy compatibility is useful. - Stage HSTS. Start with a short
max-age, monitor, then increase it. Do not addincludeSubDomainsorpreloaduntil you understand the long-term effect. - 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.
- 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-ancestorsprotection, particularly around sign-in, account, checkout and administrative actions. - Incorrect content types or user-uploaded files: fix
Content-Typeand addnosniff; 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-Controland 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-agegradually. - 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
- 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 treatHEADdifferently from a normalGET; confirm in the browser when results disagree. - Check the final HTTPS page, the HTTP-to-HTTPS redirect, apex and
wwwhosts, important subdomains, a 404 page, login or checkout routes, and any page type that uses a different application or CDN rule.
- 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.
- Start with lower-risk controls
- Correct every response’s
Content-Type, then addX-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-Optionsvalue for compatibility with older clients.
- Correct every response’s
- 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 as300seconds, then progress through longer test periods after monitoring. - Add
includeSubDomainsonly when all present and future subdomains can remain on HTTPS. - Do not add
preloadby default. Submission can affect every subdomain and removal may take months to reach browsers.
- 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-Onlyso 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-Policyheader and continue monitoring.
- 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:
- confirms that the apex domain and
wwwredirect correctly to HTTPS, but discovers a legacy subdomain that still lacks a valid certificate; - adds correct content types,
nosniffandstrict-origin-when-cross-originfirst; - sets
frame-ancestors 'self'andX-Frame-Options: SAMEORIGINbecause nobody outside the site needs to embed its pages; - starts HSTS with a short
max-agebut deliberately omitsincludeSubDomainsuntil the legacy subdomain is migrated; - tests a CSP in report-only mode and learns that the map, booking widget and consent manager require deliberate rules;
- 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-Onlyis intentionally not an enforced CSP, so a scanner may still flag the absence ofContent-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-Typevalues and addX-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
includeSubDomainsonly 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
- OWASP HTTP Security Response Headers Cheat Sheet — current defensive guidance and configuration considerations.
- OWASP Content Security Policy Cheat Sheet — CSP delivery, report-only deployment and strict-policy guidance.
- HSTS preload deployment guidance — staged
max-agerollout, requirements and the consequences of preloading. - Chrome DevTools Network reference — how to inspect response headers in the browser.
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.
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!
Founder, ScanMySEO