A TL;DR of HTTP Headers I think about once in a blue moon, after having forgotten everything I used to know about them.
Response Headers
Access-Control-Allow-Origin
The access-control-allow-origin header "indicates whether the response can be shared with requesting code from the given origin."
You use *
as the wildcard symbol, meaning any origin can request access to the resource (aka: fetch from the url).
Access-Control-Allow-Origin: *
Otherwise the response will return an approved URL.
Access-Control-Allow-Origin: https://developer.mozilla.org
Cross-origin-embedder-policy
Aka COEP
- https://blog.stackblitz.com/posts/cross-browser-with-coop-coep/
- https://web.dev/articles/coop-coep
- mdn on cross-origin-embedder-policy
I think this is saying that your page is the "embedder" and the question the browser wants answered is: "what is your policy regarding embedding other webpages within this context?" For example, if your page attempts to embed an iframe, the browser wants to know your policy so it can stop malicious behaviour that violates your policy. This is your "embedder policy".
cross-origin-embedder-policy: require-corp
The "corp" above is cross-origin-resource-policy.
Cross-origin-opener-policy
Aka COOP
If a cross-origin document with COOP is opened in a new window, the opening document will not have a reference to it, and the window.opener property of the new window will be null. This allows you to have more control over references to a window than rel=noopener, which only affects outgoing navigations.
This setting will affect your crossOriginIsolated property.
cross-origin-opener-policy: same-origin
I think this is saying your page is the "opener" and the question is: "what is your policy regarding opening other webpages within this context?" For example, if your page attempts to open an iframe, it will need to adhere to your "opener policy". This would then protect users from your web app if it was compromised.
Cross-origin-resource-policy
- mdn on the header
- mdn explainer
As this policy is expressed via a response header, the actual request is not prevented—rather, the browser prevents the result from being leaked by stripping the response body.
cross-origin-resource-policy: same-origin
The setting of same-origin
is the strictest setting and will prevent requests that are cross-origin
Referer and Referrer-Policy
When you are on website A and click a link and navigate to website B, the request to server B includes a referer
header saying the user was referred from website A.
The referrer policy is something that, for example, website A above would set to control how it is referred to in the header of the request to website B servers. Assuming I understand this correctly, this means that referrer-policy is your website informing user-agents (browsers) how you want to be referred to. The referrer headers your website servers receive from incoming requests were controlled by the incoming website's referrer policy, not yours.
strict-origin-when-cross-origin
The default referrer policy is strict-origin-when-cross-origin
, which, quoting from mdn linked above, is:
Send the origin, path, and querystring when performing a same-origin request. For cross-origin requests send the origin (only) when the protocol security level stays same (HTTPS→HTTPS). Don't send the
Referer
header to less secure destinations (HTTPS→HTTP).
Side note, "referer" is a typo that made it through the rfc process because the unix spellchecker didn't catch it in the 90s. Pretty funny.
Content-Security-Policy
It primarily helps prevent XSS attacks. XSS (or cross-site scripting) is a pervasive vulnerability. A common form of this attack is a website saves user-supplied data in an unsafe way, and then serves that content back to it's users. A malicious user can, for example, upload a dangerous script, that then gets served to other users. The browser can end up trusting the script and executing it because the script was served by the trusted website. This is known as "reflected or stored" XSS. It could also be considered a "server-side" XSS, since the vulnerability is on the server. A "DOM" XSS or "client-side" XSS involves a vulnerability that can be exploited in client-side code, for example by dangerously parsing query params that results in a manipulated DOM object, for example, a DOM that includes a malicious script element that gets executed. I don't think that this type of XSS attack is mitigated by CSP, so in what follows when I mention XSS I'm only referring to "reflected or stored" XSS.
CSP mitigates XSS (and others) by declaring safe sources of various types of content, scripts, images, videos, fonts, styles, frames, etc. For example, if you only intend for scripts to come from scripts.example.com
, then even if you were vulnerable to XSS from the example.com
domain, you could still declare that only the scripts
subdomain can serve scripts. This means the browser will know not to execute scripts from example.com
.
X-Frame-Options
It helps mitigate "clickjacking" attacks. Clickjacking is a technique that, for example, places invisible buttons on top of actual buttons, so a user's "click" has been "hijacked" to do the other action of the invisible button. The website the user visits is malicious. Your website is in an iframe being leveraged by the malicious website. If, say, the user is "logged in" to your website, or something like that, then clicking the transparent iframe button could result in the user performing an unintended action on your website that compromises their security. Some of the mitigation techniques involve ensuring your website is not within an iframe, or if it is certain user actions cannot occur.
This header is deprecated by the #Content-Security-Policy directive frame-ancestors
.
Strict-Transport-Security
- mdn on hsts (the h is for http)
- security stack exchange on how https mitigates man-in-the-middle attacks
- wiki on tls
- security stack exchange on which parts of the packets are TLS encrypted
It essentially tells the browser to only use HTTPS (and not http). Here's an example scenario from mdn (linked above)
You log into a free Wi-Fi access point at an airport and start surfing the web, visiting your online banking service to check your balance and pay a couple of bills. Unfortunately, the access point you're using is actually a hacker's laptop, and they're intercepting your original HTTP request and redirecting you to a clone of your bank's site instead of the real thing. Now your private data is exposed to the hacker.
Strict Transport Security resolves this problem; as long as you've accessed your bank's website once using HTTPS, and the bank's website uses Strict Transport Security, your browser will know to automatically use only HTTPS, which prevents hackers from performing this sort of man-in-the-middle attack.
You can set a max-age on HSTS, and it can be a year or more. So your browser would know not to visit the dangerous website via HTTP. (You should also know not to do that, too!)
Further Resources
- https://helmetjs.github.io/ (Helmet sets good default headers in express.js, it is a good source of headers and information about them. It is recommend by express.js)