Anselm Hannemann recently made a post about some of the misconceptions that front-end developers might have about web security. Since I had lots of questions about these things, I thought I’d interview Anselm to get his take on the surprising complexity of getting set up with HTTPS. We talk about things like generating certificates and how we might best make sense of the conflicting opinions many developers, including myself, have about third-party services such as Cloudflare.
For those that aren’t familiar with web security, would you mind describing the differences between HTTP and HTTPS?
Sure! The general difference between HTTP and HTTPS is simple: HTTP, or Hypertext Transfer Protocol, is the default protocol that we use to serve websites and transfer data. However, that information is sent in an unprotected, unencrypted way. HTTPS however combines HTTP and TLS (which is a cryptographic protocol) in order to protect data that is sent over a network by encrypting it.
You may wonder why you would need to encrypt the connection to your website if the content is public anyway. Let’s assume that you use a CMS, like WordPress or Craft, for your website. If you log in over HTTP to your backend, your credentials are sent in plaintext to the server. So, anyone who intercepts your WiFi or internet connection now has access to your CMS (it’s super easy, really – just think of public WiFis in cafés). But not only that, HTTPS can also protect you from getting the wrong content. If HTTPS is set up properly, hackers can’t overtake DNS to serve different content on your domain anymore. With HTTPS it’s also not possible for software on your computer to inject ads or malware into webpages.
You can think of HTTPS as the more secure version of HTTP which prevents you from data leaks to the public and also from falling for phishing.
Why do we need SSL certificates to let the browser know the connection is secure?
First, while you’ll find many people still talking of “SSL”, today we’re using “TLS” as the encryption method when we send information via HTTPS. “SSL” is an old method that shouldn’t be used anymore. HTTPS in general works with certificates, which you can get from your hosting company, to create a secure, encrypted channel in the HTTP protocol to send data. To encrypt the data you need a private key and a public key.
To make this work, you need a so called “X.509”-certificate on your server that contains the information about the site’s authenticity, approved by a root certificate authority (Let’s Encrypt, StartSSL, or similar).
All browsers, on the other hand, have a set of known and trusted root certificate authorities built-in. This is done for a more convenient user experience — the user does not need to review the certificate and approve it to establish the connection to the site. At some point you have probably seen a popup by the browser asking you if you want to trust the website connection because it’s using an unknown identity. This happens when the certificate has not been created by an official, trusted authority. Of course, there are many complex points I’m glossing over here so make sure to read more detailed resources if you’re interested in getting more information to a specific feature or technology (we link a few on the bottom of this article).
A browser needs these certificates to verify if the keys match, this ensures that neither the server, client, or anything in between has been intercepted and (accidentally or otherwise) leaked your precious data. That sounds pretty secure, but there a couple of issues in the details that could still allow attackers to intercept the connection between the client and the server. HTTPS is no magic bullet, but it does make getting at your information a lot more difficult.
your article states, I was also under the naïve assumption that all I had to do was redirect my site to
https in my server configuration file and then tell Cloudflare to switch to HTTPS. Can you describe why this is not the case?
This is not entirely wrong. So, with a service like Cloudflare things are a bit more complex. They offer a bunch of services, for example: DNS hosting, performance optimization, and security enhancements. But a lot of people sign up for Cloudflare because they provide “free SSL”. This indeed is a great feature which totally makes sense as you want to serve all your content over HTTPS, so your CDN should support HTTPS as well.
Unfortunately, and that is what most people don’t understand, they can only provide this for their part of the connection. This means that they start using HTTPS on their servers and then serve content from there to the client. If your website (the so called origin host) does not support HTTPS, this means the data is completely unprotected between your origin and Cloudflare. Even worse, this gives the user the impression that the site and data entered on the site is encrypted and protected while in fact it’s not. Cloudflare cannot modify settings on your server, so they can only do their part to make things safer. You still need to ensure that you’re providing security for the data on your origin server. That‘s what most people fail to understand.
If you did the first thing right — enabled HTTPS on your origin server — then things are slightly better. In this case, you can tell Cloudflare to only connect to your origin over HTTPS and to only serve content to the client using HTTPS. Now we have one more problem: Cloudflare’s Full SSL does not validate the origin certificate – it just uses it, so it might be invalid, self-signed, malicious. At least it means the connection between the servers is always secured by HTTPS. There is what Cloudflare calls “Full SSL strict” which validates the certificate itself, but it’s more like “Basic SSL” because you can’t ensure your customer’s data is encrypted and safe.
Cloudflare (or any other third party service) sits between browser and server and optimizes (i.e. modifies) content for delivery, or to prevent attacks on your server. The problem is that the data is unencrypted while it’s at Cloudflare. HTTPS works for the transfer but is not end-to-end encryption of the actual data sent. This means all content temporarily is unencrypted on the third party service’s machine. Even if you fully trust the company itself with your (and your client’s) data, then the problem is that another third party could gain access to such traffic-optimizing servers and read data or modify it, resulting in either the origin or the client getting modified content.
If you can, you should additionally enable HSTS, or HTTP Strict Transport Security. You do this by adding a rule to your server config that sets this flag. If you set this flag, a browser will only connect to the specified domain over HTTPS for the given timeframe. The timeframe should be set very long, Twitter for example sets it to 20 years to avoid this rule being changed in the event of an attack on their servers. You can also opt-in to include subdomains in this rule.
Finally, to prevent your site being exploited due to a compromised root certificate authority, you can set up HPKP, or HTTP Public Key Pinning, which fills the last gap on security for HTTPS. Unfortunately, if you do something wrong here, the consequences are really bad and could mean your website is not available anymore for the timeframe you’ve set (which shouldn’t be too short). You can read more on that matter and how to set HPKP up in this great article by Scott Helme.
Let’s Encrypt seems like a big step in the right direction in terms of generating certificates but this still requires knowledge of the command line. Why is basic web security so complex? Why are there not simpler solutions to these problems?
Oh yes, it’s great to finally see progress on this with Let’s Encrypt. HTTPS has been around since 1994 and so I’m quite happy that finally, people are beginning to work towards simplifying the process of setting up HTTPS. I see Let’s Encrypt only as the beginning.
Talking about this specific service. It’s just reached public beta status. Currently, it only works on the CLI and is very limited when it comes to being run without root privileges. So although it’s great to see things getting simpler, there are still too many hurdles to overcome.
I’m eagerly awaiting the point where all hosting companies begin to offer HTTPS for free with a super-easy and automated setup process of for any given domain. Because, honestly, today setting up HTTPS properly is way too complex, even for tech-savvy people.
Who do you think should be responsible for web security? Should front-end developers spend more time learning about this stuff? Or is the onus on hosting companies to figure out a more elegant technical solution to the problem — like not offering HTTP access at all?
This is a complex question that can’t be solved that easily. In an ideal world, setting up HTTPS properly for a domain would be easy as a click in a web host’s interface or a single command on a server for a server admin. There’s still a long way to go until we reach that point. Until this is the case, us developers need to take care of this.
As a full-stack or backend developer, you should take care of setting up the certificate on the server. As a front-end or full-stack developer you should take care to enable HSTS and enforcing HTTPS by default, taking care of a proper Content Security Policy, along with other security measures. Each developer, regardless of their title, has a duty to ensure the built project creates a safe and encrypted environment for its users.
Regarding not offering HTTP at all anymore—let’s talk about this again when we solved the still-remaining problems described above. Until then, I don’t believe we should aim to “deprecate” HTTP in general, especially as we still have a lot of legacy regarding hardware, cipher-support, and software out there in the world which would need to go away for a HTTPS-only world.
Which resources would you recommend so that I can learn more about web security?
Fortunately, these topics are well covered with lots of helpful blog posts out there. In general, you should read the articles written by Scott Helme to get into details of specific security features and how to enable them on your website. He has also built securityheaders.io, a tool that checks your site on how secure it is and what you should improve.
If you want to start using Let’s Encrypt for your HTTPS, Tim Kadlec’s starter post is a good idea and also his post on how to enable HSTS with it.
Finally, if you want to know more, check this security link list by Troy Hunt. And if you want to get an overview of the basic technologies then you can find good explanations on Wikipedia as well.
Usually true! Software on your local device can intercept encrypted traffic (and still inject ads). Superfish was a big (recent) one that affected many Lenovo devices.
Thanks for the nice tip on web security, bookmarked this page.
Great tips, thanks Anselm! I love seeing posts like these with good, real-world practical advice for developers and designers.
It’s important for those who build websites and apps to be more security aware as they build. It boils down to having respect for your users and their data, which is often seen as someone else’s responsibility (or is just ignored / pushed down the priority list).
We’re big believers in democratizing security at Barricade, working to promote security education and give data-based recommendations – rather than the adversarial, fear mongering approach often used to push security services.
It’s very encouraging to see more discussion like this (and tools) surfacing around good security practices!
Hey Ronan, would you mind explaining (maybe you want to do this on your website, too) how your service monitors/detects the attacks and how this might affect privacy? I could only find out that one seem to install some script on the server(?) which on the other hand opens my server to a third-party (am I correct here?).
Hey Anselm – thanks – we’re currently adding more technical detail to our site and docs to do this, appreciate the feedback!
You’re right, the monitoring is carried out by an agent you install on your server. It encrypts, then transmits data on server activity to our central engine. The agent isn’t open; for safety reasons it’s one-way only. Our engine then handles the processing and alerting of any problems we see (web app attacks, out of date software, intrusion attempts, etc).
thank you wery much
büyükçekmece çilingir http://www.buyukcekmececilingiri.com
This is pretty interesting, thank you!
Tho I think that this topic is usually discussed in the perspective of devs dealing with projects that use a private server.
What about the vast majority of small business that have a shared host webspace? Often they need no secure logins or the possibility to transfer confidential data, but the recent SEO benefits granted to HTTPS sites is indeed something that should be considered (and as specified in the article, connecting unencrypted to CMS admin panel or maybe FTP is a possible risk).
Is cloudflare the only reasonable solution for shared host websites?
Hi Gruber, the point of securing your website is to secure the visitor’s data (this regards everything that is fetched and send between the visitor and your server, content, credentials, metadata) and someone monitoring this connection could easily track personal details, behavior, political/sexual or whatever orientations and preferences. That is why providing HTTPS is not limited to when you ask for login credentials. However, if you have any kind of form on your website, as a user I’d demand you do have HTTPS enabled for your website (not just for the form endpoint because that’s pointless).
If you have a CMS you want all backend-users to only connect to the dashboard via HTTPS.
And unless you have it enabled on your shared hosting package, it doesn’t make sense to pretend HTTPS via Cloudflare. If your shared hosting provider provides you some shared HTTPS (via a generic, non custom domain) you could consider using Cloudflare. Just be aware that this connection is not entirely secure, can be intercepted. But it is still better than not choosing HTTPS at all when you have forms on your site (and let it be just your login to the CMS).
Hope this helps a bit to make these decisions. By the way, certificates aren’t that costly usually, even on shared hosting packages. What are $30/year compared to what the client pays you to develop the entire website and compared to the montly shared hosting plan ($10/month usually or more)?
Your point is absolutely the righteous norm, unfortunately the vast majority of small clients I deal with simply don’t (or worse won’t) understand.
I can barely get their attentions on this matter mentioning the potential risks while logging in the back end or using http://ftp...
Luckly enough cheap basic certs (or even free with Let’s Encrypt) will change the way this subject is actually considered…
Thank you Anselm for chiming in!
“This site may be Fake”…. I am working on a project(A Web-Education Portal ). When i open this website on my mobile device(as i always testing website by load it on free domain), then this message is open at the top of the website. And when i click on this popup box then it will redirect to this link “http://ucintsec.ucweb.com:8030/security/urlsafe….”. I don’t know why this happen ? Is any solution for the same…