{"id":14533,"date":"2016-05-03T17:16:36","date_gmt":"2016-05-03T21:16:36","guid":{"rendered":"https:\/\/blog.webmaker.org\/?p=14533"},"modified":"2019-02-26T11:23:22","modified_gmt":"2019-02-26T19:23:22","slug":"https-mixed-content-and-the-real-web-oh-my","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/foundation-archive\/mozilla-learning\/https-mixed-content-and-the-real-web-oh-my\/","title":{"rendered":"HTTPS, Mixed Content, and the real web&#8230; oh my!"},"content":{"rendered":"<div id=\"readme\" class=\"readme blob instapaper_body\">\n<article class=\"markdown-body entry-content\"><em>This post was written by <a href=\"http:\/\/pomax.github.io\/\" target=\"_blank\">Pomax<\/a>, a software engineer at the Mozilla Foundation<br \/>\n<\/em><\/article>\n<article class=\"markdown-body entry-content\"><\/article>\n<article class=\"markdown-body entry-content\"><\/article>\n<article class=\"markdown-body entry-content\">We recently fixed something around Mozilla&#8217;s X-Ray Goggles. A long running problem that caused people headaches and the feeling of lost work, while at the same time doing nothing &#8220;wrong&#8221;, from a technical perspective. This is going to be a story about how modern browsers work, how people use the web, and how those two things&#8230; don&#8217;t always align.<\/p>\n<h2><a id=\"user-content-x-ray-goggles-by-mozilla\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#x-ray-goggles-by-mozilla\"><\/a>X-Ray Goggles by Mozilla<\/h2>\n<p>So let&#8217;s start with X-Ray Goggles: the X-Ray Goggles are <a href=\"https:\/\/goggles.mozilla.org\">a tool<\/a> made by <a href=\"https:\/\/mozilla.org\">Mozilla<\/a> that lets you &#8220;remix&#8221; web pages after loading them in your browser. You can go to your favourite place on the web, fire up the goggles (similar to how a professional web developer would open up their dev tools), and then change text, styling, images, and whatever else you might want to change, for as long as you want to change things, and then when you&#8217;re happy with the result and you want to show your remix to your friends, you can publish that remix so that it has its own URL that you can share.<br \/>\nHowever, the X-Ray Goggles use a publishing service that hosts all its content over <code>https<\/code>, because we care about secure communication at Mozilla, and using <code>https<\/code> is best practice. But in this particular case, it&#8217;s also kind of bad: large parts of the web still use <code>http<\/code>, and even if a website has an <code>https<\/code> equivalent, people usually visit the <code>http<\/code> version anyway. Unless those websites <em>force<\/em> users to the <code>https<\/code> version of the site (using a redirect message), then site they&#8217;ll be on, and the site they&#8217;ll be remixing, will use HTTP, and the moment the user publishes their remix with X-Ray Goggles, and they get an <code>https<\/code> URL back, and they open that URL in their browser&#8230;.<br \/>\nwell, let&#8217;s just say &#8220;everything looks broken&#8221; is not wrong.<br \/>\nBut the reason for this is not because Goggles, or even the browser is doing something wrong &#8211; ironically, it&#8217;s because they&#8217;re doing something right, and in so doing, what the user wants to do turns out incompatible with what the technology wants them to do. So let&#8217;s look at what&#8217;s going on here.<\/p>\n<h2><a id=\"user-content-http-the-basis-upon-which-browsing-is-built\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#http-the-basis-upon-which-browsing-is-built\"><\/a>HTTP, the basis upon which browsing is built<\/h2>\n<p>If you&#8217;re a user of the web, no doubt you&#8217;ll have heard about <code>http<\/code> and <code>https<\/code>, even if you can&#8217;t really say what they technically-precisely mean. In simple terms (but without dumbing it down), <a href=\"https:\/\/en.wikipedia.org\/wiki\/Hypertext_Transfer_Protocol\" target=\"_blank\">HTTP<\/a> is the language that servers and browsers use to negotiate data transfers. The original intention was for those two to talk about HTML code, so that&#8217;s where the <code>h<\/code> in <code>http<\/code> comes from (it stands for &#8220;hypertext&#8221; in both <code>http<\/code> and <code>html<\/code>), but we&#8217;re mostly ignoring that these days, and HTTP is used by browsers and servers to negotiate transmission of all sorts of files &#8211; web pages, stylesheets, javascript source code, raw data, music, video, images, you name it.<br \/>\nHowever, HTTP is a bit like regular English: you can listen in on it. If you go to a bar and sit yourself with a group of people, you can listen to their conversations. The same goes for HTTP: in order for your browser and the server to talk they rely on a chain of other computers connected to the internet to get messages relayed from one ot the other, and any of those computers can listen in on what the browser and server are saying to each other. In an HTTP setting it gets a little stranger even, because any of those computers could look at what the browser or server are saying, <em>replace what is being said with something else<\/em> and then forward that on. And you&#8217;ll have no way of knowing whether that&#8217;s what happened. It&#8217;s literally as if the postal service took a letter you sent, opened it, rewrote it, resealed it, and then sent that on. We trust that they won&#8217;t, and computers connected to the internet trust that other computers don&#8217;t mess with the communication, but&#8230; they can. And sometimes they do.<br \/>\nAnd that&#8217;s pretty scary, actually. You don&#8217;t want to have to &#8220;trust&#8221; that your communication isn&#8217;t read or tampered with, you want to <em>know<\/em> that&#8217;s the case.<\/p>\n<h2><a id=\"user-content-what-can-we-do-to-fix-that\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#what-can-we-do-to-fix-that\"><\/a>What can we do to fix that?<\/h2>\n<p>Well, we can use <a href=\"https:\/\/en.wikipedia.org\/wiki\/HTTPS\" target=\"_blank\">HTTPS<\/a>, or &#8220;secure HTTP&#8221;, instead. Now, I need to be very clear here: the term &#8220;secure&#8221; in &#8220;secure HTTP&#8221; refers to secure <em>communication<\/em>. Rather than talking &#8220;in English&#8221;, the browser and server agree on a secret language that you could listen to, but you won&#8217;t know what&#8217;s being said, and so you can&#8217;t intercept-and-modify the communication willy-nilly without both parties knowing that their communications are being tampered with. However it does <strong>not<\/strong> mean that the data the browser and server agree to receive or send is &#8220;safe data&#8221;. It only means that both parties can be sure that what one of them receives is what the other intended to send. All we can be sure of is that no one will have been able to see what got sent, and that no one modified it somewhere along the way without us knowing.<br \/>\nHowever, those are <em>big<\/em> certainties, so for this reason the internet&#8217;s been moving more and more towards preferring HTTPS for everything. But not everyone&#8217;s using HTTPS yet, and so we run into something called the &#8220;<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Security\/Mixed_content\" target=\"_blank\">Mixed Content<\/a>&#8221; issue.<\/p>\n<h2><a id=\"user-content-lets-look-at-an-example\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#lets-look-at-an-example\"><\/a>Let&#8217;s look at an example.<\/h2>\n<p>Imagine I run a web page, much like this one, and I run it on HTTP because I am not aware of the security issues, and my page relies on some external images, and some JavaScript for easy navigation, and maybe an embedded podcast audio file. All of those things are linked as <code>http:\/\/......<\/code>, and everything worked fine.<br \/>\nBut then I hear about the problems with HTTP and the privacy and security implications sound horrible! So, to make sure my visitors don&#8217;t have to worry about whether the page they get from my server is my page, or a modified version of my page, I spring into action, I switch my page over to HTTPS; I get a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Public_key_certificate\" target=\"_blank\">security certificate<\/a>, I set everything on my own server up so that it can &#8220;talk&#8221; in HTTPS, and done!<br \/>\nExcept immediately after switching, my web page is completely broken! The page itself loads, but none of the images show up, and the JavaScript doesn&#8217;t seem to be working, and that podcast embed is gone! What happened??<br \/>\nThis is a classic case of <strong>mixed-content blocking<\/strong>. My web page is being served on HTTPS, so it&#8217;s indicating that it wants to make sure everything is secure, but the resources I rely on still use HTTP, and now the browser has a problem: it can&#8217;t trust those resources, because it can&#8217;t trust that they won&#8217;t have been inspected or even modified when it requests them, and because the web page that&#8217;s asking them to be loaded expressed that it cares about secure communication a great deal, the browser can&#8217;t just fetch those insecure elements, things <em>might<\/em> go wrong, and there&#8217;s no way to tell!<br \/>\nSo it does the only thing it knows is safe: better safe than sorry, and it flat out refuses to even request them, giving you a warning about &#8220;mixed content&#8221;.<br \/>\nNormally, that&#8217;s great. It lets people who run websites know that they&#8217;re relying on potentially insecure third party content in an undeniably clear way, but it gets a bit tricky in two situations:<\/p>\n<ol>\n<li>third party resources that <em>themselves<\/em> require other third party resources, and<\/li>\n<li>embedding and rehosting<\/li>\n<\/ol>\n<p>The first is things like your web page using a comment thread service: your web page includes a bit of JavaScript from something like <code>www.WeDoCommentsForYou.com<\/code> and then that JavaScript then loads content from that site&#8217;s comment database, for instance <code>comments.WeDoCommentsForYou.com<\/code>. If we have a page that uses HTTPS, running on <code>https:\/\/ourpage.org<\/code> then we can certainly make sure that we load the comment system from <code>https:\/\/www.WeDoCommentsForYou.com<\/code>, but we don&#8217;t control the protocol for the URL that the JavaScript we got back uses. If &#8220;WeDoCommentsForYou&#8221; wrote their script poorly, and they try to load their comments over <code>http:\/\/<\/code>, then too bad, the browser will block that. Sure, it&#8217;s a thing that &#8220;WeDoCommentsForYou&#8221; should fix, but until they do your users can&#8217;t comment, and that&#8217;s super annoying.<br \/>\nThe second issue is kind of like the first, but is about entire web pages. Say you want to embed a page; for instance, you&#8217;re <a href=\"https:\/\/en.wikipedia.org\/wiki\/Transclusion\">transcluding<\/a> an entire wiki page into another wiki page. If the page you&#8217;re embedding is <code>http<\/code> and the page it&#8217;s embedded on is <code>https<\/code>, too bad, that&#8217;s not going to work. Or, and that brings us to what I really want to talk about, if you remix a page on <code>http<\/code>, with <code>http<\/code> resources, and host that remix on a site that uses <code>https<\/code>, then that&#8217;s not going to work either&#8230;<\/p>\n<h2><a id=\"user-content-back-to-the-x-ray-goggles\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#back-to-the-x-ray-goggles\"><\/a>Back to the X-Ray Goggles<\/h2>\n<p>And that&#8217;s the problem we were hitting with X-Ray Goggles, too.<br \/>\nWhile the browser is doing the same kind of user protection that it does for any other website, in this particular case it&#8217;s actually a big problem: if a user remixed an HTTP website, then knowing what we know now, <em>obviously<\/em> that&#8217;s not going to work if we try to view it using HTTPS. But that also means that instead of a cool tool that people can use to start learning about how web pages work &#8220;on the inside&#8221;, the result of which they can share with their friends, they have a tool that lets them look at the insides of a web page and then when they try to share their learning, everything breaks.<br \/>\nThat&#8217;s not cool.<br \/>\nAnd so the solution to this problem is based on first meeting the expectations of people, and then educating them on what those expectations actually mean.<\/p>\n<h2><a id=\"user-content-give-me-https-unless-i-started-on-http\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#give-me-https-unless-i-started-on-http\"><\/a>Give me HTTPS, unless I started on HTTP<\/h2>\n<p>There are quite a few solutions to the mixed-content problem, and some are better than others. There are some that are downright not nice to other people on the web (like making a full copy of someone&#8217;s website and then hosting that on Mozilla&#8217;s servers. That&#8217;s not okay), or may open people up exploits (like running a proxy server, which runs on HTTPS and can fetch HTTP resources, then send them on as if they were on HTTPS, effectively lying about the security of the communication), so the solution we settled on is, really, the simplest one:<br \/>\nIf you remix an <code>http:\/\/...<\/code> website, we will give you a URL that starts with <code>http:\/\/<\/code>, and if you remix an <code>https:\/\/<\/code> website, we will give you a URL that starts with <code>https:\/\/...<\/code>. However, we also want you to understand what&#8217;s going on with the whole &#8220;<code>http<\/code> vs <code>https<\/code>&#8221; thing, so when you visit a remix that starts with <code>http:\/\/<\/code> the remix notice bar at the top of the page also contains a link to the <code>https:\/\/<\/code> version &#8211;same page, just served using HTTPS instead of HTTP&#8211; so that you can see exactly how bad things get if you can&#8217;t control which protocol gets used for resources on a page.<\/p>\n<h2><a id=\"user-content-security-vs-usability\" class=\"anchor\" href=\"https:\/\/github.com\/Pomax\/pomax.github.io\/blob\/master\/gh-weblog-2\/content\/posts\/markdown\/2016-05-03-18-46-33.md#security-vs-usability\"><\/a>Security vs Usability<\/h2>\n<p><a href=\"https:\/\/www.mozilla.org\/en-US\/security\" target=\"_blank\">Security is everybody&#8217;s responsibility<\/a>, and explaining the risks on the web that are inherent to the technology we use every day is always worth doing. But that doesn&#8217;t mean we need to lock everything down so &#8220;you can&#8217;t use it, the end, go home, stop using HTTP&#8221;. That&#8217;s not how the real world works.<br \/>\nSo we want you to be able to remix your favourite sites, even if they&#8217;re HTTP, and have a learning\/teaching opportunity there around security. Yes, things will look bad when you try to load an HTTP site on HTTPS, but there&#8217;s a reason for that, and it&#8217;s important to talk about it.<br \/>\nAnd it&#8217;s equally important to talk about it without making you lose an hour or more of working on your awesome remix.<br \/>\n<\/article>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This post was written by Pomax, a software engineer at the Mozilla Foundation We recently fixed something around Mozilla&#8217;s X-Ray Goggles. A long running problem that caused people headaches and the feeling of lost work, while at the same time &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/foundation-archive\/mozilla-learning\/https-mixed-content-and-the-real-web-oh-my\/\">Continue reading<\/a><\/p>\n","protected":false},"author":144,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[378228],"tags":[45511,650,395855,69],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/posts\/14533"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/users\/144"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/comments?post=14533"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/posts\/14533\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/media?parent=14533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/categories?post=14533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/foundation-archive\/wp-json\/wp\/v2\/tags?post=14533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}