{"id":2937,"date":"2026-01-23T10:33:15","date_gmt":"2026-01-23T15:33:15","guid":{"rendered":"https:\/\/csimmons.dev\/blog\/?p=2937"},"modified":"2026-01-27T09:17:42","modified_gmt":"2026-01-27T14:17:42","slug":"wordpress-site-health-security-headers-issue","status":"publish","type":"post","link":"https:\/\/csimmons.dev\/blog\/2026\/01\/wordpress-site-health-security-headers-issue\/","title":{"rendered":"WordPress Site Health Security Headers Issue"},"content":{"rendered":"<h2>Site Health Security Error<\/h2>\n<p>Security headers can be a frequently failed item in WordPress Site Health. The error in Site Health is:<\/p>\n<figure id=\"attachment_2938\" aria-describedby=\"caption-attachment-2938\" style=\"width: 569px\" class=\"wp-caption alignnone\"><img width=\"579\" height=\"224\" data-public-id=\"Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png\" loading=\"lazy\" decoding=\"async\" class=\"wp-post-2937 wp-image-2938 \" src=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_579,h_224,c_scale\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA\" alt=\"Not all essential security headers are installed\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1769181361\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA 1586w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_300,h_116,c_scale\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA 300w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_1024,h_396,c_scale\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_768,h_297,c_scale\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA 768w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_1536,h_595,c_scale\/f_auto,q_auto\/v1769181361\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26\/Screenshot-2026-01-19-at-6.50.54-PM_2938d5b26.png?_i=AA 1536w\" sizes=\"auto, (max-width: 579px) 100vw, 579px\" \/><figcaption id=\"caption-attachment-2938\" class=\"wp-caption-text\">Not all essential security headers are installed<\/figcaption><\/figure>\n<p>All of these headers can be set at CloudFlare:<\/p>\n<ul>\n<li>Upgrade Insecure Requests<\/li>\n<li>X-XSS protection<\/li>\n<li>X-Content Type Options<\/li>\n<li>Referrer-Policy<\/li>\n<li>Permissions-Policy<\/li>\n<li>HTTP Strict Transport Security<\/li>\n<\/ul>\n<h2>Review site headers using curl<\/h2>\n<p>To see what headers are being returned from a website use the following command: <code>curl -I foo.com<\/code><\/p>\n<p>curl is a command-line tool for making HTTP\/HTTPS requests. The request defaults to https.<\/p>\n<ul>\n<li>The <code>-I<\/code> parameter tells curl to:<\/li>\n<li>Send an HTTP <strong>HEAD<\/strong> request instead of GET<\/li>\n<li>Return <strong>headers only<\/strong><\/li>\n<li>Skip downloading the response body (HTML, JSON, etc.)<\/li>\n<\/ul>\n<figure id=\"attachment_2941\" aria-describedby=\"caption-attachment-2941\" style=\"width: 290px\" class=\"wp-caption alignnone\"><img width=\"300\" height=\"126\" data-public-id=\"curl_2941598b5\/curl_2941598b5.png\" loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-post-2937 wp-image-2941\" src=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_300,h_126,c_scale\/f_auto,q_auto\/v1769181872\/curl_2941598b5\/curl_2941598b5.png?_i=AA\" alt=\"curl command\" data-crop=\"2.38\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1769181872\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_300,h_126,c_scale\/f_auto,q_auto\/v1769181872\/curl_2941598b5\/curl_2941598b5.png?_i=AA 300w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/f_auto,q_auto\/v1769181872\/curl_2941598b5\/curl_2941598b5.png?_i=AA 654w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><figcaption id=\"caption-attachment-2941\" class=\"wp-caption-text\">curl command<\/figcaption><\/figure>\n<p>Cloudflare \u2013 Add a Response Header Transform Rule<\/p>\n<ul>\n<li>Log in to Cloudflare and select a domain.<\/li>\n<li>Go to <code>Rules \u2192 Overview<\/code>.<\/li>\n<li>Click <b>Create rule<\/b> and choose <code>Response Header Transform Rules<\/code><\/li>\n<li>Give the rule a clear name. Example: <code>Security Headers (WordPress Site Health)<\/code><\/li>\n<li>Set <code>All incoming requests<\/code> to <code>Apply this rule to all requests<\/code>.<\/li>\n<li>Under <b>Then<\/b>, choose <b>Set static<\/b> and enter the <b>Header name<\/b> and <b>Value<\/b> you want to add or modify.<\/li>\n<li>Click <code>Set new header<\/code> to add additional headers if needed<\/li>\n<li>Click <code>Deploy<\/code> to activate the rule.<\/li>\n<\/ul>\n<figure id=\"attachment_2942\" aria-describedby=\"caption-attachment-2942\" style=\"width: 1014px\" class=\"wp-caption alignnone\"><img width=\"1024\" height=\"906\" data-public-id=\"response-header-transform-rule\/response-header-transform-rule.png\" loading=\"lazy\" decoding=\"async\" class=\"wp-post-2937 wp-image-2942 size-large\" src=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_1024,h_906,c_scale\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA\" alt=\"Response Header Transform Rule\" data-format=\"png\" data-transformations=\"f_auto,q_auto\" data-version=\"1769182051\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/ccsimmons\/images\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA 1964w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_300,h_265,c_scale\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA 300w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_1024,h_906,c_scale\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA 1024w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_768,h_680,c_scale\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA 768w, https:\/\/res.cloudinary.com\/ccsimmons\/images\/w_1536,h_1359,c_scale\/f_auto,q_auto\/v1769182051\/response-header-transform-rule\/response-header-transform-rule.png?_i=AA 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption id=\"caption-attachment-2942\" class=\"wp-caption-text\">Response Header Transform Rule<\/figcaption><\/figure>\n<p>Recommended Header Name and Value Settings<\/p>\n<table>\n<tbody>\n<tr>\n<th><\/th>\n<th>Header name<\/th>\n<th>Value<\/th>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>Content-Security-Policy<\/td>\n<td>upgrade-insecure-requests<\/td>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>Permissions-Policy<\/td>\n<td>geolocation=(), microphone=(), camera=()<\/td>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>Strict-Transport-Security<\/td>\n<td>max-age=31536000; includeSubDomains; preload<\/td>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>X-Content-Type-Options<\/td>\n<td>nosniff<\/td>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>X-XSS-Protection<\/td>\n<td>1; mode=block<\/td>\n<\/tr>\n<tr>\n<td>Set static<\/td>\n<td>strict-origin-when-cross-origin<\/td>\n<td>Referrer-Policy<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Settings Explanation<\/h2>\n<ul>\n<li><b>Content-Security-Policy: upgrade-insecure-requests<\/b> \u2014 Automatically upgrades all HTTP resource requests to HTTPS to prevent mixed-content issues and improve transport security.<\/li>\n<li><b>Permissions-Policy: geolocation=(), microphone=(), camera=()<\/b> \u2014 Explicitly disables access to geolocation, microphone, and camera APIs for the site and all embedded content.<\/li>\n<li><b>Strict-Transport-Security: max-age=31536000; includeSubDomains; preload<\/b> \u2014 Forces browsers to use HTTPS only for one year for the site and all subdomains and signals eligibility for browser HSTS preload lists. <i>(Note: the header name should be<\/i> <i>Strict-Transport-Security<\/i>*.)*<\/li>\n<li><b>X-Content-Type-Options: nosniff<\/b> \u2014 Prevents browsers from MIME-sniffing responses and forces them to respect the declared Content-Type.<\/li>\n<li><b>X-XSS-Protection: 1; mode=block<\/b> \u2014 Enables the browser\u2019s legacy XSS filter and blocks rendering of the page if an attack is detected.<\/li>\n<li><b>Referrer-Policy: strict-origin-when-cross-origin<\/b> \u2014 Sends the full referrer URL for same-origin requests but only the origin for cross-origin requests, and nothing when downgrading from HTTPS to HTTP.\u2800<\/li>\n<\/ul>\n<h2>Confirm Response Header Transform Rule<\/h2>\n<p>To confirm the new headers are being returned use the <code>curl<\/code> command from earlier:<\/p>\n<p><code>curl -I foo.com<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Site Health Security Error Security headers can be a frequently failed item in WordPress Site Health. The error in Site Health is: All of these headers can be set at CloudFlare: Upgrade Insecure Requests X-XSS protection X-Content Type Options Referrer-Policy Permissions-Policy HTTP Strict Transport Security Review site headers using curl To see what headers are &#8230; <a title=\"WordPress Site Health Security Headers Issue\" class=\"read-more\" href=\"https:\/\/csimmons.dev\/blog\/2026\/01\/wordpress-site-health-security-headers-issue\/\" aria-label=\"Read more about WordPress Site Health Security Headers Issue\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_cloudinary_featured_overwrite":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[68],"tags":[69,77],"class_list":["post-2937","post","type-post","status-publish","format-standard","hentry","category-developer","tag-cloudflare","tag-wordpress"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pbVg43-Ln","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/posts\/2937","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/comments?post=2937"}],"version-history":[{"count":0,"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/posts\/2937\/revisions"}],"wp:attachment":[{"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/media?parent=2937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/categories?post=2937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/csimmons.dev\/blog\/wp-json\/wp\/v2\/tags?post=2937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}