Skip to content

Security headers

A few lines in the server's response telling the browser what the page may not do: guess a file's type, open inside a frame on someone else's domain, hand strangers the full address of the page.

They are sent for you. Configured in System → System Settings → Security.

What is sent out of the box

These three are on by default because they break nothing:

HeaderValueWhat it does
X-Content-Type-OptionsnosniffThe browser does not guess a file's type from its content. An uploaded "image" with a script inside stays an image
X-Frame-OptionsSAMEORIGINThe site cannot be framed on another domain — clickjacking protection
Referrer-Policystrict-origin-when-cross-originAnother site sees that the visit came from your domain, but not which page

An empty setting means "do not send this header".

Why these are on rather than left to you

A header you have to go and switch on never gets switched on, on most sites. So the safe set works out of the box, and only what can break a site asks for a decision.

What you switch on yourself

These three are off for a reason: each of them can take a working site down.

HSTS

Tells the browser the site is https-only, and for how many seconds to remember that.

The browser remembers for a long time, and you cannot take it back

Switch HSTS on for a year and you get a year during which your visitors' browsers refuse to open the site over http. A certificate expires, https breaks on a subdomain, you move hosts — and the visitor sees an error instead of a page, with no way around it.

Turn it on once https works everywhere and you trust it. Start with a day (86400) and grow.

Over http the header is not sent at all: there it is meaningless and dangerous.

Content-Security-Policy

Lists where the page may load scripts, styles, images and fonts from.

Breaks inline scripts and third-party widgets

The first time you switch it on it will kill analytics, chats, maps and everything pasted in as a <script> tag in the markup. Tune the policy on a copy of the site with the browser console open: it names every blocked source.

Permissions-Policy

Denies browser features the site does not need:

geolocation=(), microphone=(), camera=()

Look at what the site actually uses first

Denying geolocation breaks a map that shows visitors where they are. Hence the empty default: the list depends on the site, not on general principle.

Someone else's header is not overwritten

If the web server or the site has already sent a header, the component leaves it alone. A rule in nginx or .htaccess can stay as it is — there is no conflict, and it wins.

How this differs from MODX content types

MODX has its own field for headers — System → Content Types. It works, and nothing here replaces it.

The difference is reach. A content type applies to MODX resources. The component's settings apply to everything the site serves, including virtual pages and resources outside the tree: those have no content type of their own and would otherwise get no headers at all.

How to check

bash
curl -sI https://your-site.com | grep -i 'x-frame\|x-content\|referrer\|strict-transport'

Or the Network tab in developer tools — the response headers for the document itself, not for images and scripts.

© PageBlocks 2019-present