Posted: October 13, 2021
Wordpress Plugin - Security Header Generator
Managing the hosting for thousands of websites is no easy feat. WordPress makes that a tad more difficult because it currently runs over 1/3 of the websites on the internet. Keeping an application with this kind of global coverage secure should be the number 1 priority of every web hosting company, however, this is not always the case.
This plugin attempts to implement the necessary server response headers to help mitigate the most common website attacks, and allows the site managers greater and quicker control over the those headers, which would normally entail a great deal of back-and-forth discussions with their hosting companies support teams.
Why bother going this route?
Well, I have over 17 years development and server management experience and in all that time I can proudly say, I have never had one of my websites hacked.
Couple this with the fact that not every hosting company will allow you to set these headers for your site on your own, some will not even implement them if you ask them to.
Description
This plugin attempts to automatically implement the server response headers necessary to mitigate the most common website attacks, in an easy to use management interface suitable for most website managers.
It allows you to configure the headers you need and attempts to automatically generate some of the more complicated ones.
It then generates the proper server software configurations for the most common server types, just in case the hosting company your site resides on removes the ability to set the headers programatically.
Please click the More Info links below for explanations of the headers implemented.
Features
- Generates the following server response headers:
- Strict Transport Security – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
- Frame Options – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
- XSS Protection – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
- Origin Referrers – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
- Download Options – More Info: https://www.nwebsec.com/HttpHeaders/SecurityHeaders/XDownloadOptions
- Cross Origin Domains – More Info: https://webtechsurvey.com/response-header/x-permitted-cross-domain-policies
- Upgrade Insecure Requests – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests
- Decline FLoC – More Info: https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea
- Content Security Policy – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- With the help of WP CLI you can run a command on the server to attempt to automatically generate this. If you choose to use this, I would recommend running it a few times for better accuracy.
- Permissions/Feature Policy – More Info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
- Allows you to apply the headers to both the admin and the front-end of the site automatically without needing to contact your hosting company’s support team
- Attempts to generate the most common server configurations in case the headers cannot get set programatically
Directions & Settings
Install
- Download the plugin, unzip it, and upload to your sites `/wp-content/plugins/` directory
- You can also upload it directly to your Plugins admin
- Activate the plugin through the ‘Plugins’ menu in WordPress
Usage
Head over to the admin section of your site and click “Security Headers”, configure how you need it to be configured. The configured headers will automatically be implemented. Please be aware that some web hosts do not allow the header implementation utilized in this plugin (PHP), if you find this is the case for your site, head over to the “Implementation” page to see how you can accomplish this with other methods.
Once configured you can try to have the content security policy automatically generated by getting into CLI on your sites server and running the following command: wp csp generate
That will attempt to parse your entire website and gather up all external domains tied to the resource it is attached to, then create a custom post to store the results in.
You may need to run this more than once, and you will need to have some patience while it runs.
NOTE: If you are running this in a multi-site environment, you must pass the --url
flag to the WP CLI command. Making the full command: wp csp generate --url=YOUR_SITES_FULL_URL
GOTCHA
If your hosting environment is already setting these headers, most likely your settings in this plugin will NOT get overwritten with the values you specify.
If this is indeed the case, please check with your hosting company if they are, or check your server configuration for the headers getting set. The plugin will do it’s best to override them, but in some environments this is just not possible.
You can also check the Implementation tab to see if your hosting will implement the applicable configuration for you.
Settings
-
Standard Security Tab
- Apply to Admin
- Select yes or no to apply these same headers to the admin side of your site.
- WordPress Defaults
- Select Yes or No to have the plugin automatically include WordPress specific external resources in the Content Security Policy
- I have left this as an unconditional field. There may be a point in we browsers futures where it may have a use other than just the CSP
- img-src: *.googletagmanager.com *.w.org *.gravatar.com *.google.com *.google-analytics.com *.gstatic.com
- script-src: *.g.doubleclick.net *.google-analytics.com *.google.com *.googletagmanager.com *.gstatic.com
- style-src: *.googleapis.com *.gstatic.com
- font-src: *.gstatic.com *.bootstrapcdn.com
- frame-src: *.g.doubleclick.net *.google.com *.fls.doubleclick.net
- connect-src: *.google-analytics.com *.wpengine.com yoast.com *.google.com *.g.doubleclick.net
- I have left this as an unconditional field. There may be a point in we browsers futures where it may have a use other than just the CSP
- Select Yes or No to have the plugin automatically include WordPress specific external resources in the Content Security Policy
- Strict Transport Security
- Select Yes or No to have the plugin include the Strict Transport Security header to your site.
- See here for more information:Â https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
- Configure the directives accordingly.
- Cache Age: How long should browsers force HTTPS access for, in seconds.
- Include Subdomains: Include all subdomains in this rule?
- Preload: This is a Google specification. See here for more information:Â https://hstspreload.org/
- Select Yes or No to have the plugin include the Strict Transport Security header to your site.
- Frame Sources
- Select Yes or No to have the plugin add a header to configure frame sources.
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
- Configure the directive to either decline all framing, or only allow SAMEORIGIN framing.
- Select Yes or No to have the plugin add a header to configure frame sources.
- XSS Protection
- Select Yes or No to have the plugin add a header to try to prevent cross site scripting.
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
- Select Yes or No to have the plugin add a header to try to prevent cross site scripting.
- Prevent MimeType Sniffing
- Select Yes or No to have the plugin add a header to prevent mime-type sniffing.
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
- Select Yes or No to have the plugin add a header to prevent mime-type sniffing.
- Origin Referrers
- Select Yes or No to have the plugin add a header to allow only origin referrers
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
- Select Referrer Policy to send
- No Referrer: The Referer header will be omitted entirely. No referrer information is sent along with requests.
- Origin Only: Only send the origin of the document as the referrer.
- Same Origin: A referrer will be sent for same-site origins, but cross-origin requests will send no referrer information.
- Strict Origin on Cross Domain: Send the origin, path, and querystring when performing a same-origin request, only send the origin when the protocol security level stays the same while performing a cross-origin request
- No Referrer on Downgrade: The origin, path, and querystring of the URL are sent as a referrer when the protocol security level stays the same
- Origin on Cross Domain: Send the origin, path, and query string when performing a same-origin request, but only send the origin of the document for other cases.
- Strict Origin: Only send the origin of the document as the referrer when the protocol security level stays the same
- Full Referrer: Send the origin, path, and query string when performing any request, regardless of security.
- Select Yes or No to have the plugin add a header to allow only origin referrers
- Force Downloads
- Select Yes or No to have the plugin add a header to attempt to force downloading resources instead of directly opening them in the browser.
- See here for more information: https://www.nwebsec.com/HttpHeaders/SecurityHeaders/XDownloadOptions
- Select Yes or No to have the plugin add a header to attempt to force downloading resources instead of directly opening them in the browser.
- Cross Domain Origins
- Select Yes or No to have the plugin add a header to block cross domain origins. This generally is only
- See here for more information: https://webtechsurvey.com/response-header/x-permitted-cross-domain-policies
- Select Yes or No to have the plugin add a header to block cross domain origins. This generally is only
- Upgrade Insecure Requests
- Select Yes or No to have the plugin add a header to upgrade insecure requests.
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests
- Select Yes or No to have the plugin add a header to upgrade insecure requests.
- Decline FLoC
- Select Yes or No to have the plugin add a header to decline FLoC.
- See here for more information: https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea
- Select Yes or No to have the plugin add a header to decline FLoC.
- Apply to Admin
-
Content Security Policy Tab
- Content Security Policy
- Select Yes or No to have the plugin attempt to automatically generate a Content Security Policy. Selecting Yes, will open up a handful of text fields that you can add additional domains to. Please only include the FQDN, and please organize them accordingly.
- Use a space-delimited list if you need add more than one additional domain.
- This will parse the enqueued styles and scripts for the front-end of your site automatically, provided your theme has properly done this.
- This will add 2 additional headers to your site. Content-Security-Policy and X-Content-Security-Policy, configured with the detected and custom added domains to their respective content types.
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- Select Yes or No to have the plugin attempt to automatically generate a Content Security Policy. Selecting Yes, will open up a handful of text fields that you can add additional domains to. Please only include the FQDN, and please organize them accordingly.
- Content Security Policy
-
Permissions Policy Tab
- Select Yes or No to have the plugin attempt to automatically generate a Permissions Policy. Selecting Yes, will open up a handful of directives and the sources for them. If you select “Source” for any of them you will be allowed to enter a space-delimited list of URL’s to be allowed as sources.
- Please make sure to use full URL’s for the sources including the protocol used. (example: https://kevinpirnie.com)
- See here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
- Select Yes or No to have the plugin attempt to automatically generate a Permissions Policy. Selecting Yes, will open up a handful of directives and the sources for them. If you select “Source” for any of them you will be allowed to enter a space-delimited list of URL’s to be allowed as sources.
-
Implementation Tab
- This tab will generate and show you the most common server type configurations for your configured security headers. If your hosting company does not allow PHP to set the headers, you will need to copy the config for your server, and send it to your hosting company to have implemented for you in order for them to work.
Changelog
= 3.0.22 = * Fix: more array checks = 3.0.10 = * Fix: Array issue * Fix: Strict typing issue = 3.0.09 = * Feature: Implement post update hook to try to properly migrate existing settings to the new format * Update: Change exportable/importable settings names, more legible * While I will do my best to automate this, please note it may not be perfect... I am only human after all ;) * If you export your settings before updating, you can import them again after updating and the below will be taken care of for you. * Just in case it does not work 100%, please export your settings before updating to this version and perform a search and replace for the string to remove it: * Search: "kp_cspgen_" * Replace: null|nothing|empty * NOTE: If you do not export your settings I will not guarantee that you will not have to reconfigure the plugin. Although... I did take a backup ;) You will need to hop into your database to grab it though, it will be in your options table, and it is called: `wpsh_TEMP_settings`. I will have this automatically removed in a future update * Add: Option to remove server advertising. * Add: Expect-CT header * The Expect-CT header lets sites opt in to reporting and/or enforcement of Certificate Transparency requirements, to prevent the use of misissued certificates for that site from going unnoticed. * Doc: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT * Hook: `wpsh_expectct_header` * Updated: Feature Policies. * Removed the following: battery, layout-animations, legacy-image-formats, oversized-images, screen-wake-lock, unoptimized-images, unsized-media, web-share * The above no longer have any browser support. * Added: Descriptive descriptions for each directive * Updated: Content Security Policy * Added: the following fetch directives: * child-src, manifest-src, object-src, prefetch-src, script-src-elem, script-src-attr, style-src-elem, style-src-attr, worker-src, navigate-to * Added: Unsafe Inline and Unsafe Eval settings on each CSP directive * Added: Descriptive descriptions for each directive * Reworked: Settings for the entire section, which of course caused me to rewrite the way they are implemented. = 2.2.15 = * Implement: The 2 new headers documentation and implementation tabs SMH = 2.2.13 = * Deprecated: The X-XSS-Protection header has been deprecated by modern browsers. * As a result we are marking the setting, hook, and functionality to set it as deprecated and will be removed in future versions of this plugin. * Doc: https://owasp.org/www-project-secure-headers/#x-xss-protection * Set to log as deprecated * Rework: Settings Fields * found it was causing a conflict with another plugin * Add: 2 new Headers * Cross-Origin-Embedder-Policy * This response header (also named COEP) prevents a document from loading any cross-origin resources that don't explicitly grant the document permission * https://owasp.org/www-project-secure-headers/#cross-origin-embedder-policy * Hook: `wpsh_coep_header` * Cross-Origin-Opener-Policy * This response header (also named COOP) allows you to ensure a top-level document does not share a browsing context group with cross-origin documents. COOP will process-isolate your document and potential attackers can't access to your global object if they were opening it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks * https://owasp.org/www-project-secure-headers/#cross-origin-opener-policy * Hook: `wpsh_coop_header` * NOTE: There is no full browser support yet for Cross-Origin-Resource-Policy, so for now it is going to be left out. As a result, the only option for the Embedder Policy is "unsafe-none". Once it is fully cross-browser this header will be implemented. = 2.1.09 = * Fixed: Admin bar menu show in for non-admin capabilities. * Improved: Usage anywhere framework fields. * Updated: JS libraries (codemirror, leaflet, etc). * Improved: Some js and css coding. = 2.0.97 = * Verify: Core 5.9 Compatibility * Feature: Add some hooks. All pretty self-explanatory, so here is the list and arguments if there are any: * `wpsh_pre_headers`, `wpsh_send_frontend_headers`, `wpsh_send_admin_headers`, `wpsh_post_headers` * `wpsh_sts_header` - Arg: The "Strict-Transport-Security" header content for the generated options * `wpsh_ofs_header` - Arg: The "X-Frame-Options" header content for the generated options * `wpsh_xss_header` - Arg: The "X-Xss-Protection" header content for the generated options * `wpsh_mimesniffing_header` - Arg: The "X-Content-Type-Options" header content for the generated options * `wpsh_referrer_header` - Arg: The "Referrer-Policy" header content for the generated options * `wpsh_dlopt_header` - Arg: The "X-Download-Options" header content for the generated options * `wpsh_crossdomain_header` - Arg: The "X-Permitted-Cross-Domain-Policies" header content for the generated options * `wpsh_csp_header` - Arg: The "Content-Security-Policy" header content for the generated options * `wpsh_upgradesecure_header` - Arg: The "Content-Security-Policy" header content for the generated options * `wpsh_floc_header` - Arg: The "Permissions-Policy" header content for the generated options * `wpsh_permissions_header` - Arg: The "Permissions-Policy" header content for the generated options * `wpsh_pre_csp_generate` - fires off before the Content Security Policy is generated * `wpsh_post_csp_generate` - Arg: The generated Content Security Policy string = 2.0.36 = * Tweak admin permissions * found an issue where a subsite admin could not administer the settings if the super-admin disabled Plugins in settings = 2.0.08 = * Convert all major comments to phpdoc * Fix `OR DIE` on direct file access * Removed double PHP version check (whoops!) * move the plugins stylesheet * Core 5.8.1 Compliance = 1.9.51 = * Update: Rewrite Field Framework = 1.9.47 = * Update: Field Framework = 1.9.44 = * fixed minor issue setting FLoC header = 1.9.43 = * Removed sticky header for settings * it was not working properly in all browsers anyways * Implemented Permissions-Policy header * See Here for more information: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy * Organize header settings into separate tabs * Fixed issue where setting would automatically collapse * Re-implement uninstall = 1.9.27 = * WordPress Core 5.8 compliance * Tested * **feature** re-implement WP CLI functionality * Attempts to spider the site gathering up only external resources like imagery, stylesheets, scripts, fonts, frames, etc... * Creates a custom post type to hold the output of the parsed external resources * Adds the domains only to the Content-Security-Policy header = 1.9.23 = * Fix issue where admin menu would not show for some * Force PHP 7.3 minimum on actviation = 1.9.18 = * Publishing * slight issue in readme was preventing updating to 1.9.17 = 1.9.17 = * Remove the remote header checks implemented in v1.9.11 * Update Documentation = 1.9.11 = * New class to attempt server-side header Implementation * If server-side headers do exist, show a note in Settings * Attempt to override existing headers * only headers set by plugin * Cache the above check for 1 day * Temprorarily remove the CLI functionality = 1.8.23 = * Update settings framework * Updated minimum PHP requirement to PHP 7.3 = 1.8.14 = * Update for WP Core 5.7.2 * Update methods to force output type = 1.8.11 = * implement FLoC decline setting and headers = 1.7.03 = * full field framework update = 1.7.02 = * field framework update * little styling tweak for it = 1.6.10 = * fix path issue = 1.6.09 = * replace field framework * big thanks to Codestar: https://codecanyon.net/user/codestar * rebuild the settings and retrieval * rework admin sending of headers * clear cache on settings save = 1.5.22 = * update field framework * 5.7 compliance * check for existing functionality = 1.4.11 = * fix uninstall to remove all options, including for multisite = 1.4.09 = * Implement true autoloader * rename class files accordingly * Implement true autoloader for CLI * rename class files accordingly = 1.3.13 = * First public release