Multi-part series on securing our internet presence: Security Headers

“There is no such thing as perfect security, only varying levels of insecurity.” – Salman Rushdie

A multi-part series by John Ball, Phillip Kuzma, and Ted Nass on web server security.

In a hurry? Click here for the step-by-step instructions.

Security headers are part of HTTP header responses from servers to browsers that request website content. Wikipedia defines HTTP headers as:
HTTP header fields are components of the header section of request and response messages in the Hypertext Transfer Protocol (HTTP). They define the operating parameters of an HTTP transaction.”

Security headers (HTTPS Headers, HTTP Secure Headers) give specific instructions to browsers on how to load content from websites and are an easy-to-implement solution for mitigating known vulnerabilities in HTTP requests. Plus, if implemented correctly, you’ll get good marks on your security reports. 😉 is a great website/tool for scanning your server to determine what security headers are available or presented when a browser requests a connection to your web server and the status of each header option.

For example, the site ranks with an “A+” as of this posting.More details can be seen here:

For this particular site, some of the headers I set on the server back-end and using the Cloudflare front end. Others I set directly in WordPress using the “WP Content Security Policy Plugin“. In an ideal environment, these settings would be set server-side in the native server application and on the Cloudflare front end but a balance between ease of implementation and management was found (for me) using these options. A breakdown of the settings for this particular site (with clickable links for more info) are:

  1. HSTSSet Server SideSet Front End Side
  2. X-Frame-OptionsSet Server Side
  3. Content Security PolicySet Server Side w/Plugin
  4. X-Content-Type-OptionsSet Server Side
  5. X-XSS-ProtectionSet Server Side w/Plugin
  6. Referrer-PolicySet Server Side w/Plugin
  7. Expect-CTServer Side w/PluginSet Front End Side

As you can see, I tried to at least enable every option server-side using Apache options, then layered on Cloudflare protection, and as a stop-gap used a plugin to fill in the gaps.


  • Download and install the WP Content Security Policy plugin. It can be found here:
  • Navigate to “Settings” –> “CSP Options“. Ensure you save changes on each tab once set according to your needs.
  • Under the “CSP Control” tab we want to set:
    1. CSP Mode: Enforce policies
  • Under the “Content Security Policies” tab we want to set:
    1. Mixed Content: Upgrade Insecure Requests
    2. Script SRC: remove ‘unsafe-inline’
    3. Sandbox: Not Set (default unless you need to make changes)
    4. require-sri-for: Not Set (note: I use a seperate SRI plugin for managing SRI settings)
  • Under the “Headers” tab we want to set:
    1. Expect-CT
      1. Mode: Enforce Expect CT
      2. Maximum Age: One Hour (3600 seconds)
    2. X-Frame-Options
      1. Mode: DENY (unless you set x-frame/i-frame options in All In One WordPress Security then ignore this setting)
    3. X-XSS-Protection
      1. Mode: 1; mode=block – Enable Filtering, block invalid requests
    4. X-Content-Type-Options
      1. Mode: nosniff
    5. Referrer-Policy
      1. Mode: strict-origin
  • Under the “CSP V3” tab, read the caveat and, if comfortable with the warnings, click “Convert script-src to CSP V3” then save changes.
  • Head over to the “Test” tab and click “Internal Test URL Checker“. You should get a “Finished tests with no issues.” notice at the bottom of the page. If not, adjust your settings as needed.
  • Navigate over to the website and validate your settings. You should get all greens except for Strict-Transport-Security (which I set via Cloudflare after extensive testing) and Feature-Policy (which I have not had an opportunity to test. I will update this post once I test this feature.)

Feel free to comment any successes, help, or other options you used.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.