- From: Peter Eckersley <pde@eff.org>
- Date: Mon, 2 Feb 2015 16:21:00 -0800
- To: public-webappsec@w3.org
- Cc: technologists@eff.org
Apologies for joining the conversation here fairly late, and for doing so with such a long email... <TLDR>This email considers four options for fixing the current MCB+HTTPS deployment trainwreck: 0. give site operators better tools for navigating the breakage; 1. try to fix mixed content with serverside proxies; 2. change the deployed HSTS semantics while resolving the Chrome team's concerns about that; 3. add a new HSTS directive that makes the HTTPS transition easy for future client populations, leaving legacy clients with HTTP. My current vote is 3 > 2 > 1 > 0.</TLDR> As most folks here probably realise, Mixed Content Blocking (MCB) has had the unintended side effect of making transitions from HTTP to HTTPS much more difficult for a huge population of sites -- those with large HTML, JS and serverside codebases that emit same-domain and cross-domain HTTP urls for historical reasons. Though MCB is necessary for HTTPS to have the properties it is supposed to have, it is also unfortunately adding a vast amount of engineering labor to the HTTPS deployment roadmap. Our work with Mozilla et al the Let's Encrypt project and particular the Let's Encrypt agent https://github.com/letsencrypt/lets-encrypt-preview/ ; https://www.youtube.com/watch?v=Gas_sSB-5SU has made us acutely aware of these problems. As a result of MCB, there are many situations where we won't be able to automatically redirect HTTP -> HTTPS for a sys admin without a significant risk of breakage. I hope everyone can agree that the status quo isn't particularly sane. Given current clients and servers, the problem of legacy HTTP URLs would need to be fixed in billions of files on tens of millions of sites. It would be a much more pragmatic for us to fix this issue in the ~10 largest Web client codebases, and/or the ~10 largest Web server codebases. So I'd argue that this community needs to pick a strategy to make that happen. I'm going to propose four strategies, though I'm keen to hear others! 0. Really force millions of site operators to edit all their code. If we're going to do this and expect to win, we had better provide much, much better tools for doing it. Perhaps Let's Encrypt can enable report-only CSP and host analytics somewhere to tell webmasters where things are going wrong. Perhaps, instead of a mysterious MCB shield, browsers could provide a list of required edits to HTML and JS source files to fix MC. Even with measures like this, I believe option 0 would leave far too much of the work to be done by millions of fallible humans. 1. Try to deploy automated serverside fixes. Webservers, or the Let's Encrypt agent, could ship with a proxy that it commonly interposes between the HTTP server and TLS termination, which parses HTML, JS, etc, and tries to identify and fix same-origin mixed content and (where possible, perhaps by using HTTPS Everywhere rulesets) cross-origin mixed content. This could work, but will be a shamefully janky solution. Parsing HTML and JS on the serverside has a lot of correctness, performance, and some security implications we wouldn't be comfortable with. But without a change to clients' deployed MCB semantics, I think this is the best we can do. OK, so what could client implementors do? 2. Alter their HSTS implementations, so that those help solve rather than exacerbate mixed content situations. Perhaps this is only realistic within first party origins, plus those third party origins that have themselves enabled HSTS. Though I do think we should consider a more ambitious option like this: - If a site sets HSTS, all third party resource fetches are attempted over HTTPS before being blocked, but if this is happening on 3rd party domains that haven't themselves set HSTS, the site gets the angry crossed-out HTTPS UI to warn the user and admin that something squirrely and potentially dangerous is occurring. For my money, this would be an appropriate response to the conceivable but probably very rare case that 3rd party HTTPS upgrades are actually a security problem because the 3rd party server does something weird with them. I know there have been some arguments made against solution 2, summarised for instance by agl in this November thread: https://lists.w3.org/Archives/Public/public-webappsec/2014Nov/0307.html Quoting and replying: On Wed, Nov 19, 2014 at 10:30 PM, Adam Langley <agl@google.com> wrote: > Chrome applies mixed-content rules before HSTS redirects are > considered and it's unlikely that we would change that. > > Otherwise sites randomly work or not based on whether the profile has > previously visited (and thus remembered HSTS for) an origin Why not try fetching favicon.ico over HTTPS when you've about to block mixed content, allowing you to get an HSTS header if there's one to be had? > > Also, it leaves mixed-content issues to bite people using browsers > that don't implement HSTS (and possibly allow dangerous loads). Browsers that don't implement HSTS basically can't provide a secure browsing experience for human users anyway. But I do agree that there's a bit of a tension between trying to encourage the strongest possible HTTPS deployments (which is appropriate for the highest-value sites) and trying to get every last site to a great HTTPS deployment, assuming that there's a modern client there to help. Which leads me to option 3... 3. Add a new directive to the HSTS header, which sites (and the Let's Encrypt agent working on behalf of sites) can set. It could be called the "easy" or "helpful" bit. In slogan form, the semantics of this would be "if you're a modern client that knows how to do Helpful HSTS, this site should be entirely HTTPS; if you're an old client that has MCB/HSTS but doesn't know about Helpful HSTS, leave the site on HTTP". Assuming that clients are following point 6.1.4 in RFC 6797 (https://tools.ietf.org/html/rfc6797#section-6.1) correctly, it should be practical to make this kind of functionality part of HSTS. There's a question about how to get the HSTS Helpful bit to the client if the server is trying to leave the HTTP version of their site alive for clients with traditional MCB implementations. A serverside answer would be to embed a 1x1 image over HTTPS and trigger HSTS Helpful that way. A client-side answer would be to request https://example.com/.well-known/hsts-check at some point during first or early contact with a domain, and let the upgrade happen then. The Helpful bit should probably also have a way for site operators to request and control automatic upgrades of embedded third party resources. That could range from "try every third party resource over HTTPS, all of the time", through a whitelist of domains for which this should happen, through to the full gory details of putting something flexible like HTTPS Everywhere rulests in the HSTS directive. -------------- Okay, so which of these options should we pick? From first principles I would probably have gone with option 2, but given that there are so many copies of Chrome and Firefox with weird HSTS+MCB semantics in the field, the case for option 3 seems to allow more deployment with less breakage. We will build and ship 1 if that's all we can do. 0 is a good idea for sites that have the security engineering resources to do a lot of work for older clients, but we can't expect that to true of all of the hundreds of millions of sites that should be switching to HTTPS. -- Peter Eckersley pde@eff.org Technology Projects Director Tel +1 415 436 9333 x131 Electronic Frontier Foundation Fax +1 415 436 9993
Received on Tuesday, 3 February 2015 09:31:24 UTC