17 min to read
"Bank-grade" security is bullsh*t
When companies say they have 'bank-grade' security, it implies that this is the pinnacle of cyber safety. In reality, it couldn't be further from the truth.
I’m just going to come right out and say it. As the person responsible for a web-based system, it is your obligation to protect your users and their data from bad actors. It’s not optional and it’s not negotiable.
I know that this sounds like a rather aggressive statement to start off with, but in my experience, it’s far too often that someone would slap a certificate on a website and call it a job well done. A certificate is only one part of a defence in depth strategy that we must all start to condition ourselves to adopt. There is so much more you can do within the realm of web application security to keep your users, their data, and your web app safe from exploitation.
You’ve probably seen websites that tote that they have “bank-grade” security. They use that as a justification that their website is “safe” and “secure”, and you can trust them. Let me tell you right now that “bank-grade” security is bullshit.
The focus of this blog post is to explore what additional steps can be taken, why they are needed, and why the cliche of “bank-grade” security is a pretty low bar.
To that end, it’s important to understand how web security has evolved, and the threats and vulnerabilities that exist when running a web application.
Whilst most of the examples on this post mention websites, all of this information is also applicable and relevant to any web application, and I use the terms interchangeably. If you have a site, app or system that transmits information over web-based protocols, this applies to you.
Read on for an internet history lesson, or skip straight to the TLDR.
When you connect to a website over regular HTTP, there is no verification process to guarantee that server responding to your request is an authentic source. The browser assumes that this is the correct web server and data is then sent over the connection as clear text.
How HTTP puts you at risk
The primary problem with HTTP is that since all communication is sent “in the clear”, anyone can be listening at any point between you and the destination server, such as the same Wi-Fi network you’re connected to, your internet service provider, or a government agency such as the FBI or NSA. Think of it as a digital wiretap. An eavesdropper can see the web pages you’re visiting and the data you’re transferring back and forth. This interception of the traffic between source and destination is known as a “man in the middle” (MITM) attack.
You might not care so much if you’re browsing your regular news sites, but things get interesting when we introduce the transfer of sensitive information. Since there’s no verification that the webserver you are connected to is legitimate, and the content is readable by anyone that’s listening, you might think you are accessing your bank’s website but you really you’re being redirected to a fraudulent site that’s capturing your credentials.
Due to the trivial amount of effort involved in performing such an attack, browsers are beginning to update their visual indicators to signify that if you are communicating with a website over HTTP, that connection is considered “insecure”.
What is HTTPS
As the internet evolved, the secure transfer of information between client and server quickly became a necessity. RFC2128 (HTTP over TLS) introduced an extension to the HTTP protocol that encrypts the traffic between client and server using Transport Layer Security (TLS) or, formerly, Secure Sockets Layer (SSL). Even though SSL has been superseded by TLS, the two terms are often used interchangeably.
The “S” in HTTPS stands for “Secure”. HTTPS is just another name for the implementation of the HTTP over TLS. You can easily identify a website that is communicating over HTTPS via the padlock icon in the address bar.
To implement HTTPS, a certificate is required to be installed on the webserver. SSL Certificates are small data files that digitally bind a cryptographic key to an organization’s details. The binding of organization information provides authenticity, while the cryptographic keys provide the vehicle in which the information between client and server can be encrypted (See Public Key Infrastructure (PKI)).
HTTPS makes sure that a user’s browser connections are private (confidentiality), has not been intercepted (integrity), and is reaching the correct destination (authenticity). In infosec, these are the three things that are required to achieve non-repudiation.
How web security is evolving
Back in the day, SSL certificates were expensive. A hundred bucks or so for a single domain name, a few hundred for up to three domain names, and thousands if you wanted a wildcard cert. Due to high the cost of the certificates, HTTPS was typically only seen on websites that deal with sensitive information. “Regular” websites such as blogs or news sites saw the cost of a certificate unnecessary, as they had no information that they determined needed to be protected.
This is where people often get it wrong. While it may be true that a website is not hosting sensitive data, the risk to the user has not changed. Users are still equally susceptible to eavesdropping, and cyber attacks such as man-in-the-middle, phishing and pharming.
Nowadays, the barriers to obtaining certificates have been completely removed. Let’s Encrypt is a certificate authority that single-handedly democratised certificates by making them available for free. As a result, HTTPS is quickly becoming the default standard.
This shift to secure-by-default is perhaps best observed by the actions of Google in their Chromium browser engine, whereby they plan to eventually change the visual indicators in the browser address bar to “mark all HTTP pages as affirmatively non-secure.”
Don’t bloody use HTTP.
Your responsibility to your users
Your responsibility doesn’t end with keeping the backend systems and data secure. It also extends to helping to protect visitors to your website from bad actors. This means writing code that exercises good security practices to prevent exploitation using known techniques like SQL injection (SQLi) or cross-site scripting (XSS), in addition to securing the transmission of data between client and server.
Many additional configuration steps can be taken to increase the security of a connection to your site or web app. I believe that if you can implement additional controls that provide a tangible security benefit to anyone that uses your application, it would be irresponsible not to do so.
“A person may cause evil to others not only by his actions but by his inaction, and in either case, he is justly accountable to them for the injury.” - John Stuart Mill
“Bank Grade” security
When companies say they have “bank-grade” security, it implies that this is the pinnacle of cyber safety. In reality, it couldn’t be further from the truth.
To demonstrate, here are SSL reports from the “big four” Australian banks that have been assessed by SSL Labs.
SSL Labs report for commbank.com.au
SSL Labs report for anz.com.au
SSL Labs report for westpac.com.au
SSL Labs report for nab.com.au
It looks like only one doing a decent job with SSL is NAB - but this just emphasises my point. Achieving “bank-grade” security is a pretty low bar. As a consumer of a web service, you should expect better, and as the operator of a web service, you can achieve better.
To prove I’m not just all talk, here’s the same test run against this website.
SSL Labs report for mullineaux.com.au
There’s quite a bit that goes into securing the communication between server and client. Let’s dive into the details of each of the categories that define SSL security.
SSL certificate strength
There is much more to securing the connection to a website than simply throwing on any old certificate. During the certificate generation process, some critical options need to be considered such as:
The cipher strength (SHA128/SHA265 etc)
A measure of the number of bits in the key that is used to encrypt data during an SSL session. The bigger the number, the longer it takes for a computer(s) to decrypt enciphered data.
The protocol version (SSL 3.0/TLS 1.0 etc)
SSL/TLS protocols are a standard way to establish an encrypted connection between a server and a client. TLS (Transport Layer Security) is an updated, more secure, version of SSL (Secure Sockets Layer), although the terms SSL and TLS are used interchangeably.
The key exchange (Key or Diffe-Hellman parameter strength)
Diffe-Hellman key exchange is a method of securely exchanging cryptographic keys over a public channel.
The combination of how these options are configured determines the encryption strength of the data and the method in which that data is transported between server and client.
As with any system, the defences of that system need to evolve with the threat landscape around it to remain effective. Just like software, vulnerabilities have been discovered within encryption algorithms, cypher suites and transmission protocols which drive the release of new versions that resolve these vulnerabilities. Misconfiguration of these options on your certificate can potentially make your website vulnerable to attack.
If you’ve acquired your certificate from a popular free provider such as Cloudfare or LetsEncrypt, then these options should be configured correctly for you.
Certificate properties for mullineaux.com.au
However, if you’re generating certificates yourself from an internal private certificate authority then these options are something you need consider. This includes scenarios where you may be generating self-signed certificates.
HTTP security headers
To see how HTTP security headers can be used to help protect the users on your site, we first we need to understand HTTP response headers.
HTTP Response Headers are name-value pairs of strings that are returned to your client/browser in addition to the content that you request from a server. They are typically used to transmit technical information to the client such as the type of content it is, how long a browser should cache the content, the software running on the server, and much more.
Example HTTP Response headers
Security Headers are a type of HTTP response header that are used to transmit security policies to the browser.
By including security headers in your web responses, you can alter the way the browser behaves when accessing your site. This includes things like the features of the browser that are permitted (i.e. camera, microphone, geo-location etc), what types of content can be loaded, and from what sources. This will result in a safer browsing experience for your visitors and reduces the level of risk all around.
Configuring security headers
The implementation of security headers is a configuration option that must be done on the webserver that serves the content, therefore the method in which these are configured depends on the underlying web server technology. For example, the method is different for Apache vs Nginx vs IIS. Hosted platforms like Wix or WordPress usually have tools or plugins that let you configure the response headers. You’ll need to research your hosting framework to see the steps that apply to your situation.
If you don’t have access to the webserver for some reason or you’re operating a website that uses static page framework such as Jekyll or Hugo that’s hosted out of a public storage container like Azure Blob Storage or an Amazon S3 bucket, the HTTP headers can be added ‘in transit’ with something like CloudFlare workers.
Basically, there’s a method to apply security headers in any web hosting situation so there’s no excuse for thinking that this doesn’t apply to you.
Hardening your site with security headers
Now we know what HTTP response headers are and how they can be implemented, let’s take a look at some of the security headers that can be configured to achieve a result that’s better than the banks.
For a quick assessment of your security headers, check out https://securityheaders.com
HTTP Strict Transport Security (HSTS)
The Strict Transport Security header allows your webserver to explicitly tell the user’s browser that it should only interact with it using secure HTTPS connections, and never via the insecure HTTP protocol. Using HSTS means that any links, bookmarks or addresses that the user types into the address bar will be forced to use HTTPS, even if they specify HTTP.
If not applied, a bad actor can easily forward their targets to surf your site on the unsafe connection or convert HTTPS traffic to HTTP by launching a man-in-the-middle attack such as SSL strip.
Content Security Policy (CSP)
The Content Security Policy allows you to define a whitelist of approved sources where the user agent is permitted to load content for a given page. This provides a way to protect against multiple vulnerabilities such as cross-site scripting (XSS), clickjacking, protocol downgrade attacks and frame injection by restricting the type of assets (like
CSS) and the source locations from which your site will permit the content to be loaded from.
This is often used in conjunction with the HSTS header. The difference is that HSTS will redirect the initial loading of your site to HTTPS, where the
upgrade-insecure-requests directive will rewrite any links to assets within the page content to load over HTTPS. For example, if you link to a website or image within one of your pages over HTTP, the link will be changed to HTTPS before it is rendered by the client’s browser.
A full list of configurable directives for the Content-Security-Policy can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
X-Frame Options (XFO)
X-Frame-Options can be used to indicate whether or not a browser should be permitted to render a page in a
<object> HTML element. This is primarily used to avoid click-jacking attacks by ensuring that your content is not embedded with someone elses site.
Troy Hunt has a great post that explains the threat of clickjacking and how X-Frame-Options can be used to combat it.
This is a pretty simple one that only has one valid value,
nosniff. Setting this header will prevent the browser from interpreting files as a different MIME type to what is specified in the Content-Type HTTP header (e.g. treating text/plain as text/css). It helps to reduce the risk of user-uploaded content being treated as a different content-type, like an executable.
Whenever you click on a link on a website that redirects you from the original site (the origin) to another site (the destination), the destination receives information in the Referer HTTP header about the origin that you came from. This is how analytics platforms like Google Analytics can tell that 90% of the traffic to my site comes from that one LinkedIn post.
The Referer-Policy controls how much information should be included with the
no-referrer-when-downgrade directive is the default behaviour if no policy is specified. This means that all referrer information (origin, path and query string) are sent along with the referer except when the destination is less secure (i.e. HTTPS -> HTTP).
A full list of configurable directives for the Referer-Policy header can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
In a world that’s quickly adopting a “mobile-first” approach, browsers are evolving to include features that access systems commonly found in mobile devices. These include the camera, microphone, geo-location, gyroscope, payment systems (i.e. Apple Pay), light sensors just to name a few.
The Feature-Policy header allows you to explicitly declare what functionality can be used (or not used) throughout your website. If your web application doesn’t need to access the user’s camera, microphone or payment system, help protect your users by denying the browser from using these features when using your app.
Feature-Policy: camera 'none'; microphone 'none'; payment 'none'
A full list of configurable directives for the Feature-Policy header can be found here: https://github.com/w3c/webappsec-feature-policy/blob/master/features.md
Phew, this post was a big one, but we covered a lot of important stuff. Let’s recap.
- “Bank-grade” security is bullshit. Do better.
- You have a shared responsibility to your users.
- Use HTTPS. Always.
- Ensure your SSL certificates are configured properly.
- Use Security Headers to harden the content that is served from your web server and control how browsers can interact with your web application or website.
The internet was not designed with security in mind. We’ve evolved the use case far beyond what was ever envisioned by it’s design. Due to this, securing things on the web is hard. Sometimes it can feel like trying to bash a square peg into a round hole - trust me; I know them feels.
The only way it’s going to get better is by remembering that we all have an active part to play in keeping the web and it’s users safe. The best thing you can do is to make sure you are well versed in the security topics surrounding your field of expertise. This not only refers to secure design, but also keeping a continually refreshed understanding of the active threat landscape, and best practice mitigation. Users and clients will expect this from you.
For the most part, users will objectively trust the websites and applications that you put out there, and rely on you to act as their arbiters of safety on the world wide web. Don’t let them down.