You are on page 1of 7

SECURITY HEADERS

CHEAT SHEET
Security headers are HTTP response headers that help to protect your web applications.
The security headers add security controls to custom applications and/or servers that help
block or reduce the damage to your web applications and APIs from attacks. They provide
quite a bit of protection yet are often overlooked when we deploy defenses for online
systems.

This document is a cheat sheet, designed to help you select and configure the best security
headers for your applications. Spoiler alert: the more you use, and the tighter you lock them
down, the safer you and your apps will be.

Content-Security-Policy (CSP)
This is the most powerful but also time-consuming to implement of all the security headers.
CSP requires you to list all resources (scripts, images, etc.) that you want to use as part of
your site, but that are not from your own domain (usually 3rd party resources). It blocks
most XSS and framing, but also helps to block other types of attacks.

Content-Security-Policy: default-src ‘self’; block-all-mixed-content;

(this setting blocks everything, you don’t usually want to block everything)

If you plan to include anything from other domains in your app, it MUST be declared here in
CSP. If it’s not declared, it won’t work. You can do more configuration than is shown here,
but these are most likely what you will need.
object-src = plugins (valid sources for <object>, <embed> and <applet> elements)
style-src = styles (CSS – Cascading Style Sheets)
img-src = images
media-src = video and audio
frame-src = frames
font-src = fonts
plugin-types = this limits types of plugins that can be run

Note: This one is the most difficult one, feel free to ask for help from the AppSec Team!

WE HACK PURPLE
@WEHACKPURPLE
Strict-Transport-Security (HSTS)
Enforces use of HTTPS only (redirects from HTTP) for one year:

Strict-Transport-Security: max-age=31536000; includeSubDomains

X-Frame-Options
Blocks sites from framing your site. Works for older browsers, which don’t support CSP
header.

X-Frame-Options: SAMEORIGIN (you can frame yourself/from within your


domain)

X-Frame-Options: DENY (no frames at all)

X-Content-Type-Options
Block sniffing of content types, forces you to declare types. Stops sniffing attacks.

X-Content-Type-Options: nosniff

Feature Policy
Disallow or allow various HTML 5 features. Default to disallow, unless required.

Feature-Policy: camera ‘none’; microphone ‘none’; speaker ‘none; vibrate


‘none’; geolocation ‘none’; accelerometer ‘none’; ambient-light-sensor
‘none’; autoplay ‘none’; encrypted-media ‘none’; gyroscope ‘none’;
magnetometer ‘none’; midi ‘none’; payment ‘none’; picture-in-picture
‘none’; usb ‘none’; vr ‘none’; fullscreen *

Referrer-Policy
To avoid sharing previous pages browsed by users, for user privacy.

Referrer-Policy: origin
(only shows the domain they came from, not the page)

WE HACK PURPLE
@WEHACKPURPLE
The Cross-Origin Headers
The following security headers are all related to cross-origin resource sharing. These
headers are designed to ensure we share things properly (or block them from being shared
at all) as well as protect us from us from Side-Channel attacks like Spectre and Meltdown.
They do this by enforcing cross-origin isolation, which protects information that is in
memory, such as cookies, passwords, etc. It does this by rendering only a single process for
each site you visit, to protect our site from all the other sites that you have visited in case
one is vulnerable and/or malicious.

These 4 ‘new’ security headers (released in 2021) take some work to implement. Configure,
test, and, when you’re not seeing any errors when loading resources, set it to ‘enforce’.

To understand the rules for configuring the following 3 security headers, it helps to
understand a few terms they use in their settings.

‘Same-site’ means everything within the same domain, including subdomains. For instance:
https://wehackpurple.com/ and https://community.wehackpurple.com/ are both same-site,
but not same-origin.

Origin refers to the domains, scheme, and ports. If all of them are the same, they have the
same origin (same port, subdomain/domain, and scheme). For example https://wehackpur
ple.com/blogs/article1 and https://wehackpurple.com/blogs/article2 are both same-site
and same-origin.

However, https://wehackpurple.com/blogs/article1 and https://community.wehackpurple.


com/article1 are same-site, but different origin (due to different subdomain). If you wanted
to share resources between these two sites, you need to either: use none of the following
security headers (and leave yourself at risk of other sites also having access to your
resources, plus side-channel and other types of attacks) OR use the security headers below
and explicitly give permission to share. As you might have guessed, We Hack Purple wants
you to use the security headers!

You can learn more even about this, and a lot more security header goodness, from Scott
Helme: https://scotthelme.co.uk/coop-and-coep/

WE HACK PURPLE
@WEHACKPURPLE
COEP: Cross Origin Embedder Policy
This header dictates how cross-origin resources are allowed to be embedded into a
document. All cross-origin resources must be explicitly listed in CORS or CORP (more
information below), or they will be blocked.

‘unsafe-none’ is the default config value, which allows you to fetch resources from
anywhere, without the need to explicitly state them. It’s called ‘unsafe’ for a reason!

‘require-corp’ allows resources from within the same origin (your domain) and any that are
explicitly marked as “loadable” from another origin (you must list them in the CORS or
CORP headers to mark them as loadable).

Cross-Origin-Embedder-Policy: (unsafe-none | require-corp); report-


to="default"

* All of these headers support reporting via the reporting API, if you’re using REPORT-URI or
using the API directly, you can see how your security headers are protecting your app.

COOP: Cross Origin Opener Policy


This header prevents other processes from looking at your memory by breaking your app
out of the Browsing Context Group. It does this to isolate your app and its information. This
header ensures that you are not sharing a context with any other page, including potentially
hostile pages. There are levels you can configure to define your co-existence’ with other
pages inside the COOP.

‘Same-origin’ means your app shares context (and therefore potential access to the data in
stored in memory) with other pages that are in your origin AND also have their COOP
header sent to same origin. This means when you open a new window, if it’s not in the same
origin as your app, then it’s opened into a new browsing context group (protecting your app
from sharing memory and anything else stored or accessible from your origin).

If you want to share your origin with a popup, you can do this explicitly, by using ‘Same-
origin-allow-popups’.

The last option for this header is ‘unsafe-none’, and this is the default way the application
will act if you do not have this header set. It allows your page to be in the same browsing
context group as all the other pages that do not have the COOP header set. It’s called
‘unsafe’ for a reason!

Cross-Origin-Opener-Policy: (same-origin | same-origin-allow-popups |


unsafe-none); report-to="default"

WE HACK PURPLE
@WEHACKPURPLE
CORP: Cross Origin Resource Policy
This requires that all resources be explicitly permitted (listed) to be loaded cross-origin with
a CORP header. You can also define how those assets are allowed to be loaded.

The ‘same-site’ setting is the most strict, with differing subdomains being unable to load
resources from each other.

‘Same-origin’ applies to most sites, as it shares resources within your site and all the
subdomains.

‘Cross-origin’ allows everything and is only advisable if your site is required to serve
resources for others. A content delivery network would want this setting. Most other
websites would not want this setting.

Cross-Origin-Resource-Policy: (same-site|same-origin|cross-origin)

CORS: Cross Origin Resource Sharing


CORS has existed for many years, and no one considers it ‘new’ by any means. That said, it
relates to all the other ‘new’ (released in 2021) security headers. CORS tells servers that
host assets which origins (domain, port and scheme) are permitted to load those assets. It
can be used to prevent others from loading its assets, such as blocking people from
showing your copyrighted images on their sites.

CORS breaks up how to load the assets, based on the type of resource requested it will
either just do what you asked (for instance, if loading an image), or send an HTTP Options
request (to explain the complex part, for instance if you are using a less-common HTTP
method as part of your request, such as delete, trace or head) and then it will send your
intended/original request afterwards. The first request, the one with the ‘http options’, is
called a ‘pre-flight’ request, and only happens sometimes (when your request is ‘complex’).

Access-Control-Allow-Origin: domain-this-resource-can-be-shared-with

For more information, there is an excellent article by Mozilla (recommended by Scott


Helme), here.

WE HACK PURPLE
@WEHACKPURPLE
CORB: Cross Origin Read Blocking
The CORB security header is on by default in Chrome Browser versions 68 and above. Other
browsers are currently in various states of roll out. It is most well-known in developer
circles from the unfortunate few who have received the dreaded ‘blocked resource’ error
message.

Cross-Origin Read Blocking (CORB) blocked cross-origin response MY URL with MIME type
application/json.

This header blocks requests for Data Resources to be asked for as images. This means that
your application cannot be tricked into accepting JSON, HTML or XML as an image (when
you were expecting an image), which is sometimes possible without this security header. It
blocks the potentially malicious content from loading at all if it mismatches what you are
expecting, ensuring the attack is unable to self-start.

This header protects the following types of content: HTML, JSON and XML.

For this header to work properly you need to configure the cross-origin headers CORS &
CORP, plus set x-content-type-options to ‘no-sniff’. To protect these 3 data types you must
have CORS set to prevent most or all origins from loading, meaning setting the allow-origin
to anything but ‘*’. Please don’t use *, it not only negates some of your other protections,
but it also opens these 3 data types up to side-channel attacks.

X-Content-Type-Options: nosniff

AND

Access-Control-Allow-Origin: URL-of-desired-origin | definitely-not-*

* In earlier versions of Chrome, CORB is either activated together with the Site Isolation
feature or can be manually activated by launching Chrome with the following cmdline flag:

--enable-features=CrossSiteDocumentBlockingAlways

WE HACK PURPLE
@WEHACKPURPLE
Forbidden Headers
The following headers should never be used:

Public Key Pinning Extension for HTTP (HPKP): No one should use HPKP. It is
deprecated and dangerous to use. This presents (at least) medium risk to businesses.
X-XSS-Protection: This one is also deprecated. It can cause a small amount of business
risk, meaning you should ‘prefer’ not to use it. That said, there is no need to panic or
rush to remove it from legacy applications.
Expect-CT – This header was used to evaluate certificate authorities but has been
replaced by SCTs. It is no longer used.

Tip!
Use every possible security header. Think of them like seatbelts in your car: they only help
when there’s an emergency, but if an emergency happens, you will be very glad you used
them. Once you get used to adding them, it’s a breeze, and they might save you (or your
app!) someday.

WE HACK PURPLE
@WEHACKPURPLE

You might also like