..

HTTP Security Headers

HTTP security headers are response headers sent by the server to the client, to tell the browser, what security rules to enforce when handling the website’s content. The headers can be configured at the server side in http.conf for Apache. See Apache mod_headers documentation.

Content Security Policy(CSP)

Protects against XSS, injection and other attacks. If the application has already been affected XSS, CSP does not fix the issue, it only acts to block further exploitation.

Provides an allowlist for what sources the static resources(i.e CDNs) can be loaded from and how they are loaded.

CSP is fully backwards compatible. Browsers that do not support CSP will default to Same-origin policy(SOP). Likewise, a website that did not set the CSP header will default to SOP.

Example policy where all contents must come from the same origin.

Content-Security-Policy: default-src 'self'

While CSP is capable of providing functionalities seen in other headers like forcing HTTPS(HSTS), or blocking <iframe> embeds(XFO), it is still recommended to set the specific headers because:

  • Legacy browsers may not support CSP.
  • Additional headers may act as backup, and in-general, they are nice to have for defense in depth.

Considerations

  • CSP misconfiguration can break your app, consider using Content-Security-Policy-Report-Only to test and fine tune the policies.

Out of all the headers, this is the most significant one.

Refer to MDN CSP for details.

X-Content Type Options

The X-Content-Type-Options response header is a marker used by the server to indicate that the MIME types in the Content-Type headers are respected. This avoids MIME type sniffing by saying that MIME types are deliberately configured(cross-site scripting attacks that abuse MIME sniffing to supply malicious code masquerading as a non-executable MIME type).

If the Content-Type is not set properly, the resource may be rendered as HTML tags and become susceptible to XSS.

This header only has the nosniff directive.

Example: Without this header set, a plaintext file containing JS payload can be executed by the browser.

Considerations

  • Useful if the app takes user uploads and redisplays them
  • Modern browsers by default do not sniff, this header is only relevant to Internet Explorer.

HTTP Strict Transport Security(HSTS)

Tells the browser that the website can only be accessed via HTTPS protocol. Further HTTP attempts will be changed to HTTPS requests by the browser automatically.

If a website accepts a connection through HTTP and redirects to HTTPS, visitors may initially communicate with the non-encrypted version of the site before being redirected, if, for example, the visitor types http://www.foo.com/ or even just foo.com. This creates an opportunity for a man-in-the-middle attack.

preload: The preload list is maintaned by Google. It ensures that browsers will only connect to your domain via secured connection. If domain not in list, then first HTTP request will give 304(open to MITM), elif on list then 307 internal redirect.

Ensures that browsers will only connect to your domain via secured connection, maintained by a preload list(See Google HSTS preload list).

Syntax

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload

Considerations:

  • Do all the functionalities of the web app need HTTPS?
  • What if there is a need to migrate back to HTTP(this sounds terrible)?

X-Frame Options

States whether or not a browser should be allowed to render a page in an <iframe>. This header is used to avoid click-jacking attacks, as the page cannot be embedded into other websites.

It is only useful when the HTTP response where the site is included has some form of interactivity. If the site returns API requests, then it’s useless.

DENY: most secure, blocks others from framing your page SAMEORIGIN: only allow framing from the same origin(see SOP) ALLOW-FROM: allow specific sites to frame

Access-Control-Allow-Origin

This response header indicates whether the response can be shared with requesting code from other origins.

Considerations

This header cannot be set to DENY in some applications like Maps, or YouTube, as they are intended features to be included in other websites. Alas, we must know what sites should be able to frame our app.

X-XSS Protection

This header stops the page from loading if an XSS is detected. However, use of this header is heavily discouraged(depreciated), in favor of CSP in modern browsers as X-XSS-Protection can break certain websites and in some cases even cause XSS vulnerabilities in safe websites.

If there is no need to support legacy browsers, do not enable this header and use CSP without allowing unsafe-inline scripts instead.

Expect-CT

Prevents certificate spoofing, only new certificates added to Certificate Transparency logs are accepted.

Referrer-Policy

Allows a site to control how much information the browser includes with navigations away from a document and should be set by all sites. This is used for tracking, if it is not set, we can know where the site visit came from.

Permissions Policy

Locks down what features are allowed and who can use them. This includes tracking geolocation, use of webcam in the browser, etc.

Additional References

Summary

The selection of security headers will always depend on your requirements. There is no definite way for configuration.