=== EssentialHeaders ===
Contributors: alexhedstrom
Tags: security, headers, http, hsts, csp
Requires at least: 6.3
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Adds the essential HTTP security headers WordPress leaves out—on every public site response.

== Description ==

EssentialHeaders is a focused WordPress plugin that attaches the HTTP security headers browsers expect, so protection is not left to chance or buried in server config.

Under Settings → EssentialHeaders you get three tabs:

* Headers — overview of which headers are enabled and will be sent
* Settings — toggles and editable values for each header
* About — plugin info

Headers covered:

* Content-Security-Policy (CSP)
* Strict-Transport-Security (HSTS)
* X-Frame-Options
* X-Content-Type-Options
* Referrer-Policy
* Permissions-Policy
* X-Powered-By (remove it or replace its value)

Safer headers are enabled with sensible defaults. CSP starts off with a strict baseline, so you can test and allow only the sources your site needs before enabling it. Headers apply to public site responses (pages, feeds, and the login screen)—not wp-admin, AJAX, REST, GraphQL, or XML-RPC. HSTS is only sent over HTTPS. Default HSTS uses max-age only; add includeSubDomains yourself when every subdomain is ready.

== Installation ==

1. Upload the `essentialheaders` folder to the `/wp-content/plugins/` directory.
2. Activate the plugin through the Plugins menu in WordPress.
3. Open Settings → EssentialHeaders to review and configure headers.

== Frequently Asked Questions ==

= Will this break my site? =

The default set is conservative. Content-Security-Policy is off by default because a strict CSP can block scripts or styles your theme needs. Enable CSP when you are ready to tune it.

= Does HSTS work on HTTP? =

No. Strict-Transport-Security is only sent when the visitor reaches the site over HTTPS.

= Does the login screen get these headers? =

Yes. The login screen is treated as a public response. wp-admin, AJAX, REST, GraphQL, and XML-RPC are excluded, so dashboards and APIs are not broken by a strict CSP.

= Does this change site content? =

No. The plugin only stores its own options and manages HTTP response headers on public responses.

= Can X-Powered-By always be removed? =

EssentialHeaders removes PHP- and WordPress-managed instances at the latest applicable WordPress header hook. Another callback running afterward, a reverse proxy, or a web server can add the header again; remove it at that layer as well.

== Changelog ==

= 1.0.2 =
* Add: manage X-Powered-By by removing it when its value is blank or replacing it with a custom value.
* Improve: enforce managed header replacement at the latest applicable WordPress header hooks.

= 1.0.1 =
* Fix: always send security headers on front-end HTML even when the request Accept header prefers JSON. Skipping those requests let page caches store header-less responses and broke scanner results after cache warm-up.

= 1.0.0 =
* Initial release.
