This entire page is based on web security guidelines from Mozilla Infosec, the HTTP documentation from Mozilla as well as documentation from OWASP. Due to this the content on this page is licensed under CC BY-SA 4.0.
TL:DR; A web server which enforces HSTS will instruct web clients to force HTTPS on all outgoing requests, even if they are towards another domain.
The purpose of HSTS is to protect connecting web clients against downgrade attacks, from HTTPS to HTTP (see: Cloudflare). This could be performed by redirecting the legitimate user from the legitimate HTTPS server to another malicious HTTP (non-TLS) web server.
HSTS protects against this because it is actually a HTTP header which tells the browser to
Force TLS on all HTTP requests (to HTTPS)
Perform stricter error handling which regard to TLS
In addition, HSTS requires the web sever to also respond with a
max-age header (which must be at least 6 months) which the browser will use to remember for how long HSTS should be used.
Due to this TLS is a pre-requisite to HSTS and TLS must remain enabled at all times!
TL:DR; A web client connecting to a web server, which instructs the client to use X-Frame-Options, will not allow the client to render the web page in an HTTP frame to protect the user from clickjacking attacks when browsing domains.
HTTP frames such as
<iframe> has historically been used with malicious intent through Clickjacking attacks and in order to protect against them X-Frame-Options should be used. The purpose of X-Frame-Options is to prevent this with respect to HTTP frames. The reason this is relevant is that it its otherwise possible to not just render the content of a domain but also change it's appearance.
This makes it possible to make the frame transparent and place it on top of other content. In this manner, a
<button> in the invisible frame which performs, for example, a bank transaction could be aligned on top of another button which the user is compelled to press in the malicious web page.
X-Frame-Options protects against this because, In practice, when a web browser connects to a web server, the server replies with a
X-Frame-Options HTTP header which either (1) denies any framing or (2) allows framing but only for the same domain which the web server made the reply for.
TL:DR; A web browser is logged into a website, another website which the user visits may be able impersonate the user and thus perform actions as the user unless a CSRF protection mechanism is implemented.
When a user visits a website and log into their account, the web browser needs to store the something which from which the web server can derive the user's identity from. Often websites uses HTTP cookies to store a Session ID which acts as a representation of that the specific user is currently logged in.
In as long as that cookie exists the web browser will send that cookie to the web server per default in every following request to the domain which the web server is listening to. This creates the perfect scenario to perform a CSRF attack.
<body onload="document.forms.submit()"><form action="<nowiki>http://bank.com/transfer.do</nowiki>" method="POST"><input type="hidden" name="acct" value="MARIA" /><input type="hidden" name="amount" value="100000" /><input type="submit" value="View my pictures" /></form></body>
TL:DR; A web server instructs a web browser to store information in a cookie will not protect from information leakage unless the default configuration is overridden.
HTTP Cookies are stored by web browsers by instruction of the web server. The configuration of how the cookie is accessed by the browser and sent to other web servers is also defined by the web server which sent the instruction, not the browser. As such there are several settings in the configuration which needs to be taken into account.
By default there are no restrictions on how whether cookies can be sent over an unencrypted HTTP connection. Often we only want to transmit the cookie if the connection uses TLS which is exactly what the
secure directive does! It allows the web browser to be instructed to prevent sending the cookie.
document.cookie and steal it unless the
HttpOnly directive is set.
By default, when the
domain directive is not set, only the same domain which instructed the web browser to set the cookie can access it. This is most often the preferred usage.
By using the
domain directive, the web browser permits other domains and its subdomains to access a cookie. If you do not want the subdomains to access the cookie, use the
SameSite directive instructs whether the web browser should send cookies in cross-origin requests. The purpose of the directive is to offer (some) protection against CSRF attacks. The directive can be set to three distinctive values:
SameSitedirective demands that
Secure=trueis also used. The directive will not have any effect otherwise.
Strict: Will not send the cookie with any cross-origin requests and only sent to same-site requests. If you are on foo.com which has a
<a href="bar.com"> link which the user clicks, no cookies will be sent to bar.com. As such this is more suited for high security environments such as bank sites but not your average web page. If facebook.com implements
SameSite=Strict it means that if you have previously logged into Facebook you will be prompted to login again if you arrive from a google search since the Facebook cookie with your login credentials is not sent.
Lax: Similar to
Strict but will allow cross-origin HTTP
GET requests. This means that it would be possible to login to Facebook in the example above with
SameSite=Lax when the user clicks on a
<a href="facebook.com"> link. Note that
Lax still does not send cookies for AJAX, iframe, or any other request type except pure HTTP GET requests.
None: The cookie is sent with any cross-origin request whether it's pure HTTP requests, AJAX, iframe etc.
This is a relatively new feature and according to Mozilla major web browsers are implementing the directive to default to
Lax from previous default
None. If you want to read more Heroku has a great post on what the
SameSite directive means and why it is important.
TL:DR; A web browser which receives a resource with incorrect MIME type will try to identify it in a manner which could be exploited. As a preventive measure, the web browser should be instructed to reject resources with absent or incorrect MIME type.
X-Content-Type-Options header specifies how the web browser should handle resources such as stylesheets and scripts which have either an incorrect MIME type or no explicitly defined MIME type.
The usual behavior when this occurs is that the web browser tries to guess the MIME type in a manner which is implemented differently depending on the browser vendor. By using the header with the
nosniff directive, the browser is instructed to not load any resources which does not have an explicit MIME type, thereby protecting the end-user against attacks which exploit incorrect MIME type identification.
X-Content-Type-Optionshas only one directive:
nosniff. This means that the header can be regarded as a boolean where the header is either set with the
nosniffdirective or is not set at all.
<script src="malicious.domain.com"> .
In this regard, since the web client trusts the reply of the trusted web server, it will trust any content even though it is served by another domain and potentially malicious web server.
TL:DR; A web server which enforces CORS will not accept any script-initiated requests originating from a web client which is connected to a web server on any other domain unless explicitly specified.
The purpose of CORS is to limit malicious cross-domain requests and control how and from where a web server can be accessed by a client running code from a different web server.
Specifically, CORS is only applicable for cross-origin HTTP requests which occurs when all the following conditions are satisfied.
A non-user initiated request is being sent using scripts such as with AJAX or
The request (1) destination is towards another domain B.
In the example above, domain B receives a cross-origin request and thus have the ability to allow/deny the request with CORS policies using the
Access-Control-Allow-Origin HTTP header. This will instruct the web client if a content from the domain A (or any domain) is allowed to make request to domain B.
You can read a lot more about CORS in the Mozilla Developer Docs.
There are two directives which are relevant here,
The idea behind public key pinning is that a web client which, on a regular basis, connects to a given domain should verify not only that the certificate of the domain is signed by a trusted Root Certificate Authority (CA), but also which specific CA.
The purpose of HTTP Public Key Pinning is to protect the client, which has previously visited your site, from communicating with your domains in the event that the CA has changed unexpectedly. While there may be a legitimate reason behind this it may also be a result of a malicious act by an adversary.
HTTP Public Key Pinning can be a powerful tool but it is however not the most popular option as it emphasizes confidentiality and integrity over availability.
Other security features worth looking at
Set a Referrer Policy in order to prevent URL leakage to other sites.
In case CSP is not implemented or is not supported then X-XSS-Protection should be used in order to protect against [reflected cross-site scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting#Non-persistent_(reflected)) attacks.