{"id":162869,"date":"2022-09-24T01:34:25","date_gmt":"2022-09-24T01:34:25","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/fpd-custom-headers-security\/"},"modified":"2026-09-17T07:59:35","modified_gmt":"2026-09-17T07:59:35","slug":"firstpage-sg-security-headers","status":"publish","type":"plugin","link":"https:\/\/da.wordpress.org\/plugins\/firstpage-sg-security-headers\/","author":7163397,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.6.0","stable_tag":"1.6.0","tested":"6.9.8","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"Security Headers","header_author":"Joseph Mendez","header_description":"Security headers are directives used by web applications to configure security defenses.","assets_banners_color":"e8f4ff","last_updated":"2026-09-17 07:59:35","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/paypal.me\/jose88882020","header_plugin_uri":"https:\/\/www.firstpagedigital.sg\/","header_author_uri":"https:\/\/www.linkedin.com\/in\/joseph-m-3a133a29\/","rating":3,"author_block_rating":0,"active_installs":700,"downloads":6590,"num_ratings":2,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"joshme21","date":"2022-09-24 01:34:20","revision":2789535},"1.4.0":{"tag":"1.4.0","author":"joshme21","date":"2026-03-26 11:33:02","revision":3491733},"1.5.0":{"tag":"1.5.0","author":"joshme21","date":"2026-09-17 06:13:57","revision":3699612},"1.6.0":{"tag":"1.6.0","author":"joshme21","date":"2026-09-17 07:59:35","revision":3699740}},"upgrade_notice":[],"ratings":{"1":1,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":2789535,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":2789535,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":2789535,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":2789535,"resolution":"1544x500","location":"assets","locale":"","width":1550,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":2789535,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.4.0","1.5.0","1.6.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[153786,214096],"plugin_category":[],"plugin_contributors":[93489],"plugin_business_model":[],"class_list":["post-162869","plugin","type-plugin","status-publish","hentry","plugin_tags-security-headers","plugin_tags-seo-security-headers","plugin_contributors-joshme21","plugin_committers-joshme21"],"banners":{"banner":"https:\/\/ps.w.org\/firstpage-sg-security-headers\/assets\/banner-772x250.png?rev=2789535","banner_2x":"https:\/\/ps.w.org\/firstpage-sg-security-headers\/assets\/banner-1544x500.png?rev=2789535","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/firstpage-sg-security-headers\/assets\/icon.svg?rev=2789535","icon":"https:\/\/ps.w.org\/firstpage-sg-security-headers\/assets\/icon.svg?rev=2789535","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Security Headers helps site owners manage modern browser security headers from inside WordPress.<\/p>\n\n<p>Features include:<\/p>\n\n<ul>\n<li>Admin settings page under Security Headers<\/li>\n<li>HSTS controls with preload warning<\/li>\n<li>Referrer-Policy and X-Frame-Options settings<\/li>\n<li>Permissions-Policy custom value field<\/li>\n<li>Minimal enforced CSP with upgrade-insecure-requests, separate from advanced source restrictions<\/li>\n<li>Content-Security-Policy builder with Report-Only mode<\/li>\n<li>Discover \/ Review \/ Enforce workflow with explicit source approvals and policy verification<\/li>\n<li>Untrusted source suggestions from page HTML and browser CSP reports<\/li>\n<li>Saved pre-workflow settings for recovery<\/li>\n<li>Diagnostics screen showing configured headers<\/li>\n<li>Test tool to fetch and inspect your live response headers<\/li>\n<li>Import, export, and reset settings tools<\/li>\n<li>Cleanup on uninstall<\/li>\n<\/ul>\n\n<h3>Why security headers important?<\/h3>\n\n<p>When auditing websites, security headers are frequently forgotten.<\/p>\n\n<p>Although some may argue that website security is unrelated to SEO, it does become so when a site is compromised and search traffic completely disappears.<\/p>\n\n<p>Everyone who publishes content online should pay special attention to security headers.<\/p>\n\n<p>Getting hacked is not good. You lose traffic, customers and it\u2019s a pain to resolve all the issues.<\/p>\n\n<p>But good thing you\u2019re smart and have searched for this plugin :).<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin in WordPress<\/li>\n<li>Go to Security Headers in the admin menu<\/li>\n<li>Save your preferred configuration<\/li>\n<li>Purge page and hosting caches, then check the live headers on cached and uncached pages<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20content-security-policy%20enabled%20by%20default%3F\"><h3>Is Content-Security-Policy enabled by default?<\/h3><\/dt>\n<dd><p>New installs enable a minimal enforced <code>Content-Security-Policy: upgrade-insecure-requests<\/code> on HTTPS responses. It upgrades HTTP resource URLs to HTTPS without adding script or other source restrictions. Resources unavailable over HTTPS will fail to load. You can disable it using the HTTPS resource upgrades checkbox.<\/p>\n\n<p>Existing installations keep their previous behaviour and must opt in to HTTPS resource upgrades after updating. Advanced CSP remains disabled by default because source restrictions need website-specific configuration.<\/p><\/dd>\n<dt id=\"should%20i%20use%20report-only%20mode%20first%3F\"><h3>Should I use Report-Only mode first?<\/h3><\/dt>\n<dd><p>Yes, for advanced CSP. Report-Only mode reports advanced policy issues without blocking resources. The separate HTTPS resource upgrades setting remains enforced even while advanced CSP is in Report-Only mode. When advanced CSP is enforced, the baseline directive is merged into that policy.<\/p><\/dd>\n<dt id=\"does%20this%20guarantee%20an%20a%2B%20grade%3F\"><h3>Does this guarantee an A+ grade?<\/h3><\/dt>\n<dd><p>No. A grade depends on the headers actually returned for each scanned URL and the scanner's criteria. The minimal upgrade policy does not restrict script sources or provide the XSS protection of a carefully configured CSP.<\/p><\/dd>\n<dt id=\"how%20do%20i%20use%20discover%20%2F%20review%20%2F%20enforce%3F\"><h3>How do I use Discover \/ Review \/ Enforce?<\/h3><\/dt>\n<dd><ol>\n<li>Open Security Headers &gt; Discover \/ Review \/ Enforce and acknowledge Start \/ Resume Discovery. On first use, this saves a settings backup and replaces advanced CSP with a same-origin Report-Only starter. This does not block advanced policy violations; the separate HTTPS upgrade baseline remains enforced if enabled.<\/li>\n<li>Purge page, hosting, and CDN caches. Browse important pages and exercise forms, booking, chat, lazy loading, analytics, login roles, and consent states. HTML detection suggests scripts, styles, images, fonts, frames, media, and manifests. Browser reports provide additional origins for dynamic requests, CSS dependencies, APIs, and workers. The plugin does not fetch external JS\/CSS files or execute JavaScript to crawl the site.<\/li>\n<li>Review suggestions. Approve recognised required origins or reject unwanted suggestions. Unsafe inline\/eval and broad data\/blob script permissions require a separate risk acknowledgment; manually configured hashes\/nonces can be preferable. Discovery never automatically includes sources in the policy. Existing manual CSP fields remain explicit configured permissions, so rejecting a suggestion does not override them.<\/li>\n<li>Verify the public Report-Only policy for a same-site page path. The tool does not add cache-busting parameters or follow redirects. It requires HTTP 200 HTML with the matching policy. This confirms one response, not full site coverage. Approvals and policy changes invalidate verification.<\/li>\n<li>With no pending suggestions, confirm browser testing and cached-page header coverage, then use Enforce Reviewed Policy. The fixed policy contains approved origins plus manual fields; it never expands based on HTML or public reports. Purge caches again and verify the enforced policy. Resume Report-Only testing before changing approvals.<\/li>\n<\/ol>\n\n<p>Use Restore Saved Settings to return to the full plugin configuration saved before the first workflow start. Normal settings saves cannot skip verification and directly enforce a changed reviewed policy. Imported settings are returned to Report-Only for retesting.<\/p><\/dd>\n<dt id=\"can%20discovery%20prove%20that%20every%20asset%20is%20safe%3F\"><h3>Can discovery prove that every asset is safe?<\/h3><\/dt>\n<dd><p>No. Detection is a compatibility aid, not a security audit. Public browser reports can be forged and are never treated as trusted approvals. The plugin may miss features not exercised, conditional requests, logged-in variations, and reports that do not arrive. Missing reports do not prove safety. Origin approvals permit more than a single file, and broad permissions in manual fields can weaken CSP. Discovery is capped at 250 source\/directive pairs; reports are limited to 16 KB, 20 entries per batch, and 60 entries per client per minute. Limits can prevent complete observations.<\/p>\n\n<p>New installs use the reviewed-source workflow and disable automatic source inclusion. Existing installations keep legacy settings until an administrator explicitly starts discovery. Legacy automatic inclusion can also permit attacker-injected sources and is retained only for compatibility.<\/p><\/dd>\n<dt id=\"where%20are%20discovery%20data%20and%20browser%20reports%20stored%3F\"><h3>Where are discovery data and browser reports stored?<\/h3><\/dt>\n<dd><p>In bounded WordPress options on your own site, not in an external service unless you configure an external report endpoint. Page paths are stored without visitor query strings or fragments. Reports and source suggestions are untrusted. Removing the plugin through WordPress uninstall deletes its settings, reports, discovery, verification, and workflow backup options.<\/p><\/dd>\n<dt id=\"why%20are%20headers%20missing%20on%20cached%20pages%3F\"><h3>Why are headers missing on cached pages?<\/h3><\/dt>\n<dd><p>Page caches, hosting proxies, and CDNs can serve HTML without running WordPress. PHP headers cannot cover those responses. Apache rules can cover static cache files when Apache processes the plugin's generated .htaccess rules, but Nginx does not read .htaccess. Ask your host to apply security headers at the cache-serving layer and avoid duplicate headers. Purging caches alone may not solve the issue if the cache bypasses WordPress again.<\/p>\n\n<p>Auto-detected advanced CSP requires WordPress to inspect rendered HTML. It cannot detect sources in a static cache response. Emergency CSP bypass also requires a WordPress-generated response and cannot bypass policies enforced by your server or CDN.<\/p><\/dd>\n<dt id=\"does%20hsts%20work%20on%20http%20sites%3F\"><h3>Does HSTS work on HTTP sites?<\/h3><\/dt>\n<dd><p>No. HSTS should only be enabled when your site is fully available over HTTPS.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>Added a Discover \/ Review \/ Enforce admin workflow with explicit, nonce-protected source approvals.<\/li>\n<li>Added HTML and browser-report suggestions for static and dynamic resource origins without automatic trust.<\/li>\n<li>Added public Report-Only header verification, policy-change invalidation, and explicit enforcement confirmations.<\/li>\n<li>Added iframe, media, worker, and manifest directive fields and a fixed-policy preview.<\/li>\n<li>Preserved legacy settings on upgrade and saved pre-workflow settings for recovery.<\/li>\n<li>Added modern Reporting-Endpoints\/report-to support alongside report-uri and bounded Reporting API batches.<\/li>\n<li>Hardened public reports with size, origin, rate, and source-validation limits.<\/li>\n<li>Added cleanup for workflow data on uninstall.<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Added an independent enforced upgrade-insecure-requests baseline for HTTPS responses.<\/li>\n<li>Enabled the baseline for new installs while preserving existing installations until they opt in.<\/li>\n<li>Kept advanced CSP configurable and Report-Only testing independent of the baseline.<\/li>\n<li>Merged the baseline into enforced advanced CSP without duplicating the directive.<\/li>\n<li>Prevented static Apache baseline rules from overwriting auto-detected enforced advanced CSP.<\/li>\n<li>Added HTTPS upgrade diagnostics, resource compatibility warnings, and cache guidance.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Added best-effort CSP source detection from rendered HTML.<\/li>\n<li>Added a built-in CSP violation report collector and browser-only emergency bypass.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Added diagnostics and live header testing tools in wp-admin.<\/li>\n<li>Added import, export, and reset tools for plugin settings.<\/li>\n<li>Added a configurable Content-Security-Policy builder with Report-Only support.<\/li>\n<li>Added uninstall cleanup for stored plugin options.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added a WordPress admin settings page under Settings &gt; Security Headers.<\/li>\n<li>Added saved plugin options with sanitization and safer defaults.<\/li>\n<li>Connected PHP and Apache header output to the saved admin settings.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Updated plugin metadata for modern WordPress compatibility.<\/li>\n<li>Removed deprecated legacy headers.<\/li>\n<li>Limited default headers to a conservative modern set to reduce breakage.<\/li>\n<li>Only sends HSTS on HTTPS requests.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release<\/li>\n<\/ul>","raw_excerpt":"Security headers are directives used by web applications to configure browser-side security defenses.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/162869","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=162869"}],"author":[{"embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/joshme21"}],"wp:attachment":[{"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=162869"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=162869"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=162869"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=162869"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=162869"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/da.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=162869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}