Headers and CORS
12 answers
What goes back to the browser, and what a browser may do with it.
Looking for something specific
The searchable index covers all 326 answers at once and filters as you type.
147 Add a header of my own to every response
Open the site, Settings tab, Headers, Custom response headers. One per line, name then value. Save, then Apply config.
This is where a header goes if it is not one of the named boxes further down. Cache hints for a CDN in front, a build number so you can tell which release answered, or a header your monitoring looks for.
148 Turn on CORS for an API
Open the site, Settings tab, Headers, and tick Enable CORS. Then:
- Allowed origins: the sites allowed to call this one,
one per line, each with its scheme.
https://app.example.com, notapp.example.com. - Tick the methods you actually use. GET is always allowed. POST, PATCH, DELETE, OPTIONS and HEAD each have a box.
- Allowed request headers: anything unusual the caller sends, such as
Authorizationor a custom API key header.
Do it on the API path rather than the whole site if the site also serves pages. And resist putting a star in Allowed origins on anything that needs a login. A star means every website on the internet, which is fine for a public price list and very much not fine for anything else.
149 My browser says the CORS preflight failed
A preflight is an OPTIONS request the browser sends first, asking whether the real request is allowed. Three things trip it up, in this order:
- OPTIONS is not ticked in the methods list. The preflight itself is an OPTIONS request, so leaving it out blocks everything.
- The header is not in the list. If the caller sends
Authorizationand you did not list it in Allowed request headers, the browser stops before it ever sends the real request. - The origin does not match exactly. Scheme, name and port all have to match.
https://app.example.comandhttps://app.example.com:443are the same thing to a person and different strings to a browser.
The browser console names which check failed, and it is worth reading properly rather than guessing. It is more specific than it looks.
150 Allow cookies on a cross origin request
Tick Allow credentials under Headers. The caller also has to ask for it, so
their fetch needs credentials: "include".
You cannot use a star in Allowed origins with this on. Browsers refuse that combination outright, because it would let any site on the internet make requests as your signed in user. List the real origins.
151 Turn on HSTS
Open the site, Settings tab, Security, tick HSTS (force https) and set HSTS duration.
HSTS tells a browser never to use plain http for this name again, for as long as the duration says. That closes the gap where somebody types the name, gets sent to http first, and can be intercepted before the redirect happens.
Start at a day while you check nothing broke. Move to a year once you are sure. Once a browser has been told, you cannot take it back, so do not set a year on a name you might want on plain http next month.
Apply HSTS to all subdomains covers every name under this one, including names you have not made yet. Powerful and easy to regret.
152 Stop my site being put inside a frame on somebody else's page
Open the site, Settings tab, Security, Frame embedding policy:
- Nobody can frame this site. The right answer for anything with a sign in page.
- Only this site can frame itself. Use this when your own pages embed each other.
- Do not send the header. Anybody may frame you.
This is what stops clickjacking, where somebody puts your page in an invisible frame over their own and collects clicks meant for something else.
153 Add a Content Security Policy without breaking the site
Write the policy in Content Security Policy under Security, and tick CSP in report-only mode before you save.
Report only means the browser tells you what would have been blocked and blocks nothing. Leave it that way for a week, watch the browser console on the real site, and widen the policy until it stops complaining. Then untick it.
A policy applied straight to a real site takes out the analytics, the fonts and half the images within about a minute, and the failures are silent unless somebody happens to have the console open. Report only first, every time.
154 Stop browsers guessing what a file is
Tick Stop content type sniffing under Security.
Without it, some browsers ignore what you said a file is and decide for themselves based on what is inside it. An upload saved as a text file can be treated as a script and run. With the box ticked, the browser believes what you said and nothing else.
There is no real downside as long as your server sends the right types, which this one does.
155 Control what gets sent in the referrer
Open the site, Settings tab, Security, Referrer policy. Every link out of your site normally tells the other site which page the visitor came from, query string and all.
Send only the domain, and only over https is a good default. The other site learns you sent the traffic and learns nothing about which page or which search.
Tighten it further if your addresses contain anything private, such as a document identifier or a reset token. Those end up in other people's logs otherwise.
156 Stop telling everybody what web server I run
Open the site, Settings tab, Security, Server header. Remove it completely is the default and the right answer. There is also an option to replace it with something of your own, and one to leave nginx alone.
Separately, Show nginx version controls whether the exact version number goes out. Leave that off. A version number turns a general scan into a targeted one.
None of this is real security on its own. It just means somebody has to do the work rather than being handed the answer.
157 Turn off browser features I do not use
Open the site, Settings tab, Security, Permissions policy. This is where you say the page has no business asking for the camera, the microphone, the location, or the accelerometer.
It matters most when your page embeds anything you did not write. Turning off what you never use costs nothing and removes a whole shelf of things a script could try.