Robert Miller

Robert Miller


Security headers for applications

What are security headers, and how can I use them to help better secure my website?

What are security headers, and how can I use them to help better secure my website?
Security headers for applications
When creating your awesome new website (I am sure it is super awesome!), there are a few commonly missed security aspects you should consider to help keep your website safe. I'll list some common ones that I feel are relevant.

What are security headers

The term "security headers" is a really just a blanket term used to describe headers that are sent to the browser from the server that can help prevent some common issues with XSS and other types of attacks. These headers provide instructions to the browser about the policies you create for your website, such as not allowing images to load from other websites, all the way to disallowing microphone access.

When should I think about using them?

I personally find it a good practice to consider using these types of headers early on in the development of a new project for 4 reasons.
• Your project planning, involving resources, can be better thought out
• It forces you to use good practices right from the start
• You know your future visitors can be safe from these types of attacks up front
• Implementing things like CSP later on could be rather difficult

When you consider the above 4 reasons, it can be very convenient to think about and implement these types of protections early on in a projects lifespan.

Who should use them?

This is a very good question that is certainly specific to each individual application. For example, maybe your project is an internal one that only you and a handful of trustworthy people use and therefore it is not really a high priority. Other times however, you may work on a project that is open to the public or otherwise can be consumed by large numbers of individuals, and you may consider this a higher priority.

Additionally for large existing applications, some of the recommendations may be too restrictive, as it may require changing the entire flow or aspect of large features or an entire application itself. So it is important to evaluate your own applications needs and how it may fit into some of these types of policies.

Security headers

Below, I will list some headers that may be of interest and offer some details on each one.


# Deny all frames X-Frame-Options: DENY # Deny frames not from your hostname X-Frame-Options: SAMEORIGIN

This header is useful for not allowing your website to be loaded inside of iframes, frames, objects or embeds. For example, let's say an attacker wraps your website in an iframe, and above the iframe they add a login feature of their own. This could effectively trick a user of your website into entering their credentials into a website not owned by you.

Pro: Prevent your website from being put into an attackers frame on their website
Con: Disallowing your website from being put into a frame for legitimate reasons (eg: youtube embedded videos)

This header can also be considered deprecated when using CSP (Content Security Policies) which we'll go into below.


X-Content-Type-Options: nosniff

This can be a useful addition to any website. This tells the browser to use the mime type specified by the server, such as "text/css" by a stylesheet and not to try and guess the content type if it believes it is something different than what the server specified. This keeps you in control of the content and can help prevent an issue where your content can be misinterpreted by the browser and be rendered in unexpected ways, which could lead to security issues.

This also enables CORB (Cross-Origin Read Blocking) on some resources as well, which prevents the browser from delivering certain cross-origin network responses to a web page, when they might contain sensitive information and are not needed.

Pro: Ensure the right content is being delivered and protected
Con: None


# Recommended: No referrer information sent Referrer-Policy: no-referrer # Do not send referrer info when going from https to http Referrer-Policy: no-referrer-when-downgrade # Only send the origin Referrer-Policy: origin # Send the origin, path, and query string when it is the same origin and same protocol level. Send only the origin for cross origin requests and requests to less secure destinations Referrer-Policy: origin-when-cross-origin # Send the origin, path, and query string for same-origin requests Referrer-Policy: same-origin # Second Best: Send only the origin when the protocol security level stays the same and do not send to less secure destinations Referrer-Policy: strict-origin # Default: Send the origin, path, and query string when performing a same origin request. For cross-origin requests only send the origin when the protocol security level stays same. Do not send to less secure destinations Referrer-Policy: strict-origin-when-cross-origin # Not Recommended: Send it all to everywhere Referrer-Policy: unsafe-url

This has a lot of options, but in security terms; This can prevent sending information to websites that might not be in your control or accidentally leaking potential sensitive information. A good article to read on why this is important, would be this one (which we are not going to be sending your referring information to as well 😊):
The referrer problem

Pro: Protecting your visitors information a little better
Con: Understanding your applications needs to share information between different applications


Content-Security-Policy: default-src 'none';

There is certainly an extensive list of directives this policy takes so I won't cover them all, but I will explain the essential concept and provide links to documentation and a neat little site you can use to generate a policy.

The header Content-Security-Policy tells the browser how to essentially treat your websites resources. Lets pretend an attacker was able to inject some JavaScript in to your application. Using a proper content security policy could prevent that code from ever even running. Let's take a look at this websites content security policy and explain what is happening for a better explanation:

default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests; disown-opener; base-uri 'self'

Whoa, that is a long string. Lets break it down one by one:

default-src 'none'; This tells the browser that the default src for all of my resources is nothing. This means for example if I do not specify a src for images, no images will load.
script-src 'self'; Only this website ('self') can load scripts, scripts from 3rd parties will not load
style-src 'self'; Only this website, and "" can load stylesheets
img-src 'self'; Only this website can load images
font-src 'self'; Only this website, and "" can load fonts
frame-ancestors 'none'; This website will not load in frames, similar to the "X-Frame-Options" header discussed above
form-action 'self'; This website can only submit forms to itself
upgrade-insecure-requests; This one is pretty optional, and not necessarily needed by this website specifically. Its intent is to opportunistically load http resources as http
base-uri 'self'; Only this website can be used in a element

As you can see above, these strict sets of rules help keep things more secure and also help keeps our code a little more clean as we are not allowing inline javascript or inline css. Not allowing inline javascript and inline css also helps keep our site secure.

Pro: Strong control over website content
Con: With a large existing website, it can be a large task depending on how strict you go

More reading:
Auto-generate CSP

Testing headers

There are a few good websites you can use to test some of these headers and more. I'll list a few links below:
Mozilla Observatory
Security Headers
Geek Flare

WordPress Plugin

I created a small WordPress plugin to test your WordPress website for these types of headers. I'll link a zip file and a link to the GitHub repo below.
Download Plugin
View Source Code

Wrapping things up

There are definitely more headers to consider, such as "Strict-Transport-Security" which requires your website only load in https, and some cross origin request headers. This is just a basic list of things you can do to get started and hopefully set you up on a path to a more secure application. Like previously stated, these things will not directly apply to every situation, so it is best to analyze individual applications to determine your own best path forward.