Hacker News new | past | comments | ask | show | jobs | submit login
How to implement HTTPS in an insufficient manner (troyhunt.com)
135 points by tomelders on April 4, 2013 | hide | past | favorite | 64 comments



The author lists 5 problems, but all of them have to do with the fact that the website in question is not 100% HTTPS. So it's really just one problem that has many different implications.

When you maintain both an HTTP site and an HTTPS site, it's nearly impossible to toss state back and forth between them without exposing yourself to at least one of these problems. Even if you do everything perfectly, people will complain that they get logged out when they visit HTTP URLs. The only solution is to treat HTTP, from now on, as if the only response it could produce were:

    HTTP/1.1 301 Moved Permanently
    Location: https://www.example.com/remainder/of/url
That's it. If you handle personal information, never send "200 OK" responses over plain HTTP, ever.

Need more server resources? Maybe. And this is probably why 99% of websites that have the problem the author mentions resist making changes. But the "HTTPS uses more server resources!" complaint is so 20th-century it's not even funny anymore. If you're not going to invest in 10% more server resources (or 5%, or 25%, or whatever) to protect your users' personal information, I seriously doubt that you deserve anyone's business in the first place.


> all of them have to do with the fact that the website in question is not 100% HTTPS

Problem number 4 is actually also relevant for HTTPS-only websites. That is, if the website doesn't use HSTS, and most don't.

Also a 301 only works for one page. Consider this: You go to example.com (typed in address bar), it redirects you to https://example.com via a 301, then you load your favorite news website, I inject an iframe in the news website that loads http://example.com/pwnd, and the browser happily sends the cookie (if it wasn't set to secure-only).

The HSTS header is what you need to do, not only a 301.


> Problem number 4 is actually also relevant for HTTPS-only websites.

You're right, but I was thinking along the lines of: The reason why they don't set secure cookies is probably because they want to share state between their HTTP site and their HTTPS site.

> Also a 301 only works for one page.

You can make it work on every page. Even the query string will remain intact. POST requests are more complicated, but they are usually triggered by forms and JS on your own pages, so you have more control over that.

    RewriteEngine on
    RewriteCond %{HTTPS} !on
    Rewrite (.*) https://www.example.com/$1 [L]
Of course, this doesn't solve the insecure cookie problem. But again, I'm assuming that not being HTTPS-only is the root of all evils.


By the way, you will probably want to apply [B] to that rewrite rule. In order for mod_rewrite to do its thing, it has to URL-decode the path, which means that you will get decoded data in the $1 capture. In some cases, the resulting URL (after mod_rewrite) may end up being corrupted -- for example if there's a URL-encoded slash or question mark. The [B] flag tells mod_rewrite to URL-encode backreferences. The process is not guaranteed to end up with the same URL, but with [B] it is at least a bit safer.


Of course you can activate the 301 on all pages, I actually assumed that, but it was about the cookie that can be stolen via problem #4.


> Need more server resources? Maybe.

AWS does this for (almost) free - load balancing includes optional SSL termination. really simple to set up, all HTTPS traffic just forwards to port 80 on your instance.


No, please don't do this:

If a visitor goes to http://domain/some/url they should not redirect to https://domain/some/url - it makes it harder to catch pages that use the wrong protocol.

Better to redirect http://domain/some/url to https://domain

Edit: if you're logging referrers from your own domain with non https:// urls AND using secure cookies, ignore my comment!


That would make for terrible UX, and I'd expect most users to just shrug it off as your website being weird, so it wouldn't even help you "catch pages that use the wrong protocol".

Why not just do the redirect that you know is right, but log it (with referer, so you know what needs fixed)?


Nooo, don't erase the address that took me 5 minutes to type. What you say doesn't make any sense. You should obviously configure the https redirect as a site wide setting and not per page.


That's clearly true from the usability perspective. However, the problem is that bulk redirections like that make it very difficult to catch insecure resources.

For example, let's suppose you have a secure page that's referencing some JavaScript resource via a plain-text connection. Because of the redirection, the browser will ultimately fetch the required file, but only trying plain-text HTTP first. That one plain-text request can be hijacked by a man-in-the-middle attacker and abused to take over the victim's browser (and account).

Further, if your users have bookmarks to plain-text pages, their first access to your web site is always going to be insecure, which means that they can be attacked via sslstrip.

These problems are solved with Strict Transport Security, but it will probably take some time until we can fully rely on it.

In the meantime, the plain-text URL can be preserved, and the redirection carried out via an intermediary page that explains why links to plain-text pages are dangerous. It's ugly, but I don't think there's a better (safer) way.


Yes, these are real problems, but how is redirecting to the home page helping in any way? When the user navigates back to the page she wanted the in-secure script will still be fetched. A MITM is still able to serve a copy of your page.


I wasn't arguing for redirecting to the home page, only to avoid redirecting (to the intended destination on port 443) automatically.

If a user's browser ever sends a port 80 request, you've already lost (assuming the MITM is there). On your end you may even never see a plaintext request. But in all other instances, displaying an intermediary page is a chance to educate your users, and possibly get them to change their bookmarks.

Further, with little work you may be forcing the MITM to do some custom coding (a lot of work) in order to make the attack seamless.

I wouldn't do this for just any web site, but if you're running a bank or something similarly sensitive, it would probably be worth it.


If a user's browser ever sends a port 80 request, you've already lost (assuming the MITM is there).

Not really. Although old browsers don't support HSTS, they still respect the "secure" flag in cookies. So if an old browser ever requests an insecure resource, no cookies are sent with it, so the bad guys can MITM your connection all day long and no harm will be done. You only need to make sure that your own web pages never request resources over HTTP, and this is relatively easy to do.

> On your end you may even never see a plaintext request.

If so, there's no point doing fancy redirects anyway. How do you redirect a request that you never see? Therefore this scenario isn't really worth losing sleep over.

> displaying an intermediary page is a chance to educate your users, and possibly get them to change their bookmarks.

Users don't want to be educated, period.

Also, technically when a browser encounters a 301 redirect, it should update the relevant bookmark automatically. In reality no browser does this, but that's what the standards say anyway.


> Although old browsers don't support HSTS, they still respect the "secure" flag in cookies. So if an old browser ever requests an insecure resource, no cookies are sent with it, so the bad guys can MITM your connection all day long and no harm will be done.

Not true. Once a MITM hijacks the victim's communication with the server, she can do whatever she wants, including stripping the "secure" flag from session cookies. She may not be able to compromise a previous secure cookie, but she can hijack a brand new session, wait for the user to authenticate, and gain access that way. The communication from the victim to the MITM will be plain-text with insecure session cookies; the communication from the MITM to the server can be SSL with secure cookies.

And if we're talking just about an insecure resource (not a page, but, for example, a JavaScript file), the MITM can simply inject malicious code into it and hijack the browser that way.


How about this: You run two instances of Apache, one only loaded with the rewrite rule and only serving on :80, and check those logs regularly?


You can check the logs even with a single web server instance, provided you keep separate access logs for ports 80 and 443. But people don't do that. Forcing the web site to break is also forcing the developers to realize there is a problem, and to deal with it.


I'm the guy who originally contacted Troy Hunt about this, as he mentions in the blog post.

What annoys me is I'm a very young developer, and I've only really just become interested in security (12 months ago I didn't even know what hashing was!!!), yet there's developers out there with years and years of experience making huge sites for the likes of Tesco and TopCashBack for vast sums of money and they don't think about incorporating even the simplest foundations of internet security a novice like me would implement without even thinking! How is this possible?! If I'm doing it in tiny little php sites with 1 unique visitor ever, why are these 'experts' not in there huge corporate sites with hundreds of thousands of users a month?!


I could cite multiple reasons, but the main one I see is that the people who pay for and specify the requirements of a project are often nontechnical and don't delegate any decision making authority to technical personnel, no matter how much talent is in the pool. Repeated attempts to bring up issues are met with blank stares, as if a foreign language is being used (and to nontechnical people, it is). I've gotten calls at 5 PM on a Friday that "Our new site (hosted on a third party server) is going live on Monday! We need a domain and an SSL certificate." In a corporate or institutional environment, bureaucratic obstacles can make such a request impossible. Throw in a VIP who won't budge, and you're about to ruin the weekend for multiple employees who will remain gun-shy about disclosing any problems in the future.


Years and years of experience? Often not, and that's speaking from years and years of experience!

Vast sums of money? Yes, at least the outsourcing vendors who churn this sort of thing out.

Unfortunately you're the exception Mark so good on you for that. Well I mean unfortunate for the greater web using population, but very fortunate for you!


To expand further on those points with a personal anecdote... I worked on a "big website" for a very big government department. I was still in university at the time, had about a year's experience with the platform, and was earning close to callcenter wages.

The government only contracts to companies on a particular whitelist, which we weren't. They paid a company something in the region of £300,000 for the website.

That company then outsourced 100% of the work to the tiny (single digits employee count) company I was at.

They paid us £40,000.

My share of that works out at about £2,000.

The fact something cost half a million dollars in no way implies any kind of quality, or that the people working on the software will know what they're doing. (Really: another horror story involved a website that only needed to work in IE6... and had been built and tested purely in Firefox)


I'm scared to death of making a more-subtle security mistake that can be exploited. I find it surprising that people can be so negligent.


Businesses care about loss, not security as an intrinsic merit. They will invest it only to the extent to which problems are actively costing them sales, raising expenses like insurance or are required to comply with some sort of regulation (government, credit card processor, etc.).

Something positive like a site redesign perceived as increasing customer appeal or negative like an expensive legacy server upgrade often trumps security unless it clearly poses a future risk – this is also why many large companies tend to follow the trailing edge as the main concern is usually avoiding a lawsuit alleging that they were significantly worse than everyone else in their industry.


Because huge corporations often prioritize other things over technical expertise, and experts often prefer to work in settings other than huge corporations.


"Years and years experience"

This is not always the case. Lots of marketing/PR companies started off in the pre-Internet days, and simply added websites to their list of services and rely solely on the experience of their devs to handle the rest. I was a contractor for such a company and to cut costs (read: to save on paying me), they hired a junior developer with no formal education, who specialized in copy-paste programming to do many of their large sites. He's since left, but the damage he's done still lives on in the countless sites he built for their clients, which are full of horribly insecure code (especially #1 on the HTTPS no-no list).

The good news is that, following his departure, I got plenty of work doing clean-up jobs on all the sites he built. :)


How is this possible?!

In any sufficiently large organization, the people who make the decisions and the people who enact those decisions are separated by distance, background, experience, or other reasons. This is why you see so much dysfunction in large organizations, and it extends to politics and other things that affect you as well. Look for it and you'll start seeing it everywhere.


This is the same guy who exposed similar flaws with Tesco's (UK supermarket chain) systems [1].

Why on Earth these companies are given free advice, but think they (or their PR folks) know better is beyond me. Take the advice! You've now got a security flaw, documented, waiting for Joe Hacker to take your customer's data and shoot a hole through your business, and its reputation.

[1] http://www.troyhunt.com/2012/07/lessons-in-website-security-...


I emailed my ISP today to ask them why my password was being stored in plain text (and not even escaped) in a MySQL database. Their response was that everything was "working", so I didn't have to worry. Bear in mind, this is a company with my banking details.

I have absolutely no expectation that it is going to be fixed either.


How do you know they do?

That said, you should have seen my face when my ISP emailed me my very password for online access, in plain text. It was something like 123456. Unforgivable double offense.


Their tools truncated my changed password to 25 characters silently (first clue), their password reset tool emailed the plaintext password back to me (second clue), and their "api" endpoint errors out when I use special characters in my password (last clue).


These companies likely have staff that already are acutely aware of the problems. It is sometimes very difficult to change anything from the inside, sometimes you need some negative PR to actually get the ball rolling.


Could someone explain to me why storing un(salted/hashed) passwords is such a big thing? Sure, it doesn’t hurt to salt and hash passwords[0], but since users aren’t supposed to reuse passwords anyways, what's the problem in storing 7UgHxJYjkgWDyCa9gsrH rather than db5670ac4a274055e3f785300bec563c48306bf3ab8cb32223a4cd311984a3b4?

[0] And possibly normalise their length/character set, something that comes for free with hashes.


Firstly, an attacker with access to your backend database will have full access to user credentials if passwords are not salted and hashed. An attacker can then sign in as any user. The attacker may not be trying to steal all your have and may instead be looking to make life difficult for a single specific user.

Secondly, users will reuse passwords. An attacker with access to the plaintext password and the user's email address can use this to try to gain access to other services.

Thirdly, the attacker in the first example could be a disgruntled employee. You don't want a disgruntled employee causing trouble.

Lastly, I like to protect myself. A user of your services may claim you or your employees are signing in as them. It is convenient to be able to honestly state that this cannot happen.


I give you the first three points, though at least the first one sounds a little academic, given that someone with access to the backend database could probably effect queries ‘simulating’ an active user.

However,

> Lastly, I like to protect myself. A user of your services may claim you or your employees are signing in as them. It is convenient to be able to honestly state that this cannot happen.

sounds odd, since the user transmitted their password in clear text to the server at least once when registering, unless you use browser-side hashing/salting, in which case this hash would then take on the role of a password (i.e. wouldn’t help at all). Furthermore, anyone with database access could overwrite the hash in the database, log in with the password matching the new hash and then put the old hash back in place.


> Furthermore, anyone with database access could overwrite the hash in the database, log in with the password matching the new hash and then put the old hash back in place.

With a salt, it removes all doubt. If an employee has a grudge against one customer, they could take the unsalted pass, and authenticate as that customer, no database transactions; essentially no paper trail.

If that scenario happened on a hashed and salted database, you'd have transactions that X employee changed the salt & hash, then 20 minutes later changed it back. As soon as (CEO/CTO/Mr. Manager) finds that out, X employee is held accountable for their actions.


I'm guessing you're trolling, but I'll bite...

" given that someone with access to the backend database could probably effect queries ‘simulating’ an active user."

Yes, in shortsightedland. In a company where storing plaintext passwords is normal, it's not too far fetched to think that they are probably backing up and restoring their databases all over the shop.

They only need to lose a laptop on public transport and now they've basically distributed ALL their users common passwords.


> since users aren’t supposed to reuse passwords anyways

Never design for what people are supposed to do. Design for what people actually do.


Users do reuse passwords, even if they shouldn't. Defence in depth.


> Defence in depth.

Thanks.


Another point:

If someone has read-only access to the database (e.g. a junior developer) they can do absolutely nothing with a hashed password


Really? Absolutely nothing! Except social engineering would be extremely easy with all that data about a user.


What users do is not necessarily the same as what they should do.


Probably the same reason civil engineers design every individual component several times stronger than they need to be. Redundant safety points mean multiple things have to simultaneously fail instead of just one thing.


SSL should really be all or nothing. The same way browsers don't like loading insecure content from a secure origin, they should also squirm at the idea of submitting a form to a secure area (from non-secure) -- including if the parent is non-secure. An iframe isn't good enough.


Do i have to pay or create accounts on third party services to use HTTPS (in nginx)?

I never used https on my sites because there are some giant warnings ("dangerous") in browser when you go to a website that is self-signed. No warnings on plain http.


You can get a free SSL certificate at https://www.startssl.com/ , so that should not be a reason to keep you from using it.

I do agree that the extreme mistrust of browsers towards self-signed certificates is an odd thing.


> I do agree that the extreme mistrust of browsers towards self-signed certificates is an odd thing.

No, not at all; it's the whole point of SSL. The guy MITMing an SSLed website can create a cert for that site himself, but he can't get it signed by a CA. So he has to sign it himself. Thus, from the browser's perspective, all self-signed certs are possible instances of "there used to be a CA-signed cert here, but now you're being MITMed."

Now, that's not to say something like self-signed certs wouldn't be nice--given some sort of distributed pin cache, we could have something closer to an SSH/PGP model where everyone's current self-signed cert "fingerprint" is on file, and alarm bells go off if you see a cert different from the one you're supposed to see. But without that, self-signing is literally no more secure than no SSL at all: anyone else can also self-sign to MITM you.


> but he can't get it signed by a CA.

I strongly doubt that.


Well, like I said--it's the whole point of SSL. If he can (and the CA responsible isn't immediately shut down), it means SSL is fundamentally broken.


It's free but they charge you to revoke a certificate, which is quite unfortunate as it discourages people from revoking if they e.g. leak their private key.


Browsers mistrust self-signed certificates because that's what a MITM attack would look like.


You could also think about getting CAcert(ified?) and promote the CAcert root certificates getting included in more browsers. This is not measurably more insecure since SSL is mostly snakeoil anyways as long as you rely on external entities[0] to verify the identity of websites.

Ideally, browsers would store the certificate presented on the first visit to a website and compare the certificate presented on following visits to that stored certificate to warn the user on mismatches – so far, I have not yet found a usable implementation thereof, and especially not one more widespread than CAcert.

[0] Among them such trustworthy companies as DigiTrust, TÜRKTRUST or CNNIC.


http://www.startcom.org/ has free certs for non businesses. or it's about 10$ a year for a paid one


Https article served over http. Lovely.

Edit: Besides that problem #1 is offtopic since it has nothing to do with https and that 3/4 other points are captain obvious, #4 is actually a good one. It's so obscure that many will forget to enable it ("all pages are secured anyway"), but whenever a user visits any http page, an attacker can inject a small frame loading the http version of my website, and even if I redirect, the cookie was already sent and read by the attacker. Only an HSTS header or enabling the secure-cookie option protect against this.


If there was something worth protecting on a personal blog site, it might be a different story.

1 is very on-topic - there's no way that data should be sent in the clear.

HSTS is good, but unfortunately only partially supported. Agree on the secure cookie, but of course you need to drop the dependency on accessing it over HTTP before you do that.


> If there was something worth protecting on a personal blog site, it might be a different story.

It's not about security here, it's about privacy.

https://willnorris.com/2012/12/all-https-all-the-time

> This blog isn’t terribly controversial. But if only the "controversial" stuff is private, then privacy is itself suspicious. Thus, privacy should be on by default.


HTTPS is not really that effective for privacy. An attacker can still see what site you visited (Well, the IP, but it would be fairly trivial to get the domain as well) and with a little bit of analysis could most likely make a fairly accurate educated guess about exactly which page you requested.


>> ...and with a little bit of analysis could most likely make a fairly accurate educated guess about exactly which page you requested.

Could you elaborate on this? I would have assumed that with the request URI being encrypted that this would be extremely difficult (load times/payload size maybe?) for all but the simplest of sites.


Yeah, essentially it comes down to timings/measuring payload lengths. Even for complex websites it may still be possible to attempt to infer what you're viewing. For example, if you are interested, take a look at this research paper which explains how to capture what a user is typing in an auto complete (i.e sends a request every time you type a character) box even over an encrypted connection:

http://research.microsoft.com/pubs/119060/WebAppSideChannel-...

Which could leak information about what you're looking at or looking for. The site is not mentioned specifically in the paper but Amazon uses a autocomplete for it's search which exhibits similar behaviour to what is discussed in the paper. So even on a site like Amazon if you visited it over a secure connection an attacker could most likely find out what you are searching for or looking at on Amazon.


Thanks for the explanation and the link, much appreciated!


If every blog on the internet had a static IP to serve HTTPS over, we'd have even less IP addresses available than we do now.


this went from good motivation for ipv6 switchover to obsolete excuse: http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI


IPv6 or SNI


SNI has the added merit of working on practically everything these days.


I almost didn't read past the introduction, where he claimed a secure form in an unsecured page meant that the contents of the submitted form would be transmitted in the clear.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: