Please read my blog's comment policy here.
Update: IE9 includes improved handling of Mixed Content. Click to learn more...
As we developed Internet Explorer 8, we spent quite a bit of time pondering what to do about IE7’s infamous “Mixed Content” warning prompt:
As I noted on the IEBlog four years ago, the mixed content warning occurs when a web developer references an insecure (http) resource within a secure (https) page. Such references create vulnerabilities that put the privacy and integrity of an otherwise-secure page at risk, because the insecure content could be modified in transit. If added to the DOM, insecurely-delivered content can read or alter the rest of the page even if the bulk of the page was delivered over a secure connection. These types of vulnerabilities are becoming increasingly dangerous as more users browse using untrusted networks (e.g. at coffee shops), and as attackers improve upon DNS-poisoning techniques and weaponize exploits against unsecure traffic.
From a security standpoint, our best option would be to suppress the prompt altogether and simply make the secure choice on the user’s behalf, blocking all insecure content in secure pages. Unfortunately, as I mentioned in my MiX 2009 Security session, security is usually easy, but tradeoffs are often hard. If we were to simply automatically block the insecure content, we risk confusing the user; pages which rely on insecure images, stylesheets, or scripts could appear broken. In the worst case, the user might think the broken pages indicate a bug in IE8 and subsequently revert to an older version of the browser to get the prompt and unbroken pages.
In an attempt to resolve the compatibility / security tradeoff, we experimented with a number of concepts. For instance, we tried blocking insecure content in secure pages by default, with an information bar that allowed refresh of the page with mixed content permitted.
In our testing, we discovered a number of important scenarios where this approach introduced a much more severe problem-- data loss. For instance, when the user is composing a blog post or email message on a secure site, they might type or copy/paste a reference to an insecure resource within that message. When the information bar is subsequently used to unblock the mixed content, the blog post or email message would be lost because the web application was refreshed. If we didn’t refresh the page after permitting the mixed content, the page could break anyway, because the insecure resource would be run out of its normal order.
Ultimately, we concluded that removing the prompt wasn’t feasible. In IE8, we continue to rely on web developers to fix their pages to remove insecure content vulnerabilities; pages without such vulnerabilities won’t trigger the prompt.
Though we couldn’t get rid of it entirely, we did make some improvements to the prompt to correct several violations of our secure design principles. We identified three major problems with the older version:
1> The secure choice is not the default option.
2> The prompt does not clearly identify that the user is being asked to make a security decision.
3> The prompt does not offer the user enough information to make a safe choice. Specifically, it doesn’t indicate what the consequences of their choice might be.
To address these issues, we changed the default behavior of this prompt such that the secure option is the default; if the user simply clicks through, the page remains secure. We also updated the title, question, and explanatory information to help users understand the implications of the security decision they are being asked to make. The new prompt appears as follows:
If the user chooses “No,” then the insecure resources are displayed in the page and the lock icon is removed from the browser address bar.
If you encounter a mixed content warning, feel free to point the website administrator to the following section of this blog post to help them fix the bug in their site.
Users may choose to suppress mixed content warnings by adjusting browser security settings. Inside the Tools / Internet Options / Security / Internet Zone / Custom… dialog, the “Display mixed content” option can be set to “Disable.” This option will automatically block insecure content in secure pages without the annoyance of the prompt. In many cases the web page will not be seriously broken; in some cases, no user-visible change will occur, for instance, if the insecure content was a tracking pixel or metrics-tracking script.
Similar configurations can be made to the Intranet Zone and Trusted Zone settings. Within some organizations, it may be appropriate to set the Intranet zone option to “Enable,” because it is less likely that an attacker outside the organization could exploit Intranet sites containing mixed content. In contrast, while it might be tempting to set the “Trusted” zone setting to “Enable,” it’s important to remember that in the face of a DNS-poisoning or man-in-the-middle attack, even “trusted” HTTP traffic could be intercepted.
Note: There's one other important factor to keep in mind-- IE checks the Security Settings for the Zone of the insecure content, not the Security Settings of the Zone of the page. Intuitively, that's seems quite backwards, doesn't it? It certainly seemed surprising and wrong to me when I first learned about it.
However, if you think harder about it, it turns out that it makes perfect sense: you (the user) may know that you have a "safe" connection to a particular zone (say, the Intranet) and hence any content that is coming from that Zone can be transfered without HTTPS but remain secure (say, because your organization's firewall prevents tampering by external attackers). In contrast, if you were visiting a HTTPS page on your Intranet, and it tried to pull in insecure content from the Internet, it would be incorrect for the browser to say "Well, the outer page is trusted, so we'll let unprotected content from another source be mixed in."
For security and user-experience reasons, mixed content vulnerabilities should be fixed by the web developer. In principle, this is very simple: within a HTTPS page, never include a link to a HTTP-delivered resource.
One trick which might be useful is to use protocol-relative hyperlinks, of the form “//example.com/image.gif”. When the user visits a secure page containing such a reference (e.g. https://example.com/page.htm) the resulting URI will be evaluated as https://example.com/image.gif. On the other hand, if the user visits the same page using HTTP, the resulting URI will be evaluated as http://example.com/image.gif. In this way, site developers can easily build pages that work for either HTTP or HTTPS without introducing a mixed content vulnerability.
If you simply remove the SRC attribute from this tag (since it's not performing a download), you will find the problem goes away.
If you encounter a mixed content warning while working with your site, you may be able to use IE’s built-in developer tools to search for the insecure reference. However, it’s also possible that a HTTPS URL returned a redirect to an insecure resource, which could be difficult to determine by examining the DOM alone. The Fiddler web debugger can help troubleshoot the problem; simply follow these steps:
1> Start Fiddler
2> Clear the browser cache
3> Hit CTRL+F5 to reload the page
4> In Fiddler, click the Protocol column to sort by requests by protocol
6> Eliminate the use of those HTTP URLs or update any secure redirectors pointing to HTTP resources
By removing mixed content vulnerabilities, you can protect the integrity and privacy of the content on your secure pages, and avoid annoying your visitors with this security prompt.
Thanks for your help in securing the web!
Why you can't turn off this warning for trusted sites. Time to switch to Firefox...
@Prior poster: You *can* turn this warning off for any site you want, and this blog post contains a screenshot clearly showing how to do so. As noted in the blog post, if you want to make a change, I recommend you move the setting from "Prompt" (the default) to "Disable."
The point of this blog post is that the "Enable" setting exposes you to a security risk that many people don't recognize, *even for sites you trust*. This blog post explains the source of that risk. The risk is one that you would face with ANY browser, so switching browsers doesn't help you in any way.
The best fix, as shown by this post, is for websites with Mixed Content vulnerabilities to fix those vulnerabilities.
So, basically the only option was to be royally annoying to anyone who visits many major sites?... Google included. I understand the security concerns, but this new message box is actually more misleading than any of the previous ones. Additionally, there shouldn't be an all or nothing when considering this option.
The box is misleading in the sense that when you read the warning, it is inverse to most warning-prompts where they ask you "Do you want to show the content?" and you click yes, here, its "Do you want to block the content?" and you have to click No. So when you see "Mixed Content", your initial response is to say "yes! show that content to me" (if you understand the risks and don't want the page to break). However, when users click that, the page breaks anyways.
Furthermore, when you consider what to do to get rid of this sometimes very annoying pop-up, you can either go "Totally Accept", "Totally Reject", or "Annoying Pop-Up". What would, perhaps, be more appropriate would be a sort of "Whitelist" that will automatically accept traffic from certain websites. This way, users who frequent certain sites and trust them can disable the prompt on that site only, but still get the prompt if they visit a new site which has the vulnerability. Users could add sites to the whitelist directly from the prompt and then remove sites at a later time from the Internet Options dialogue.
This just seems like a much more practical solution than creating a terrible browsing experience on major websites which haven't bothered to upgrade to standards, potentially only in the sense of their banner ads display from HTTP instead of HTTPS.
If a major site isn't using HTTPS properly, blame should properly accrue to that site, and the site should be fixed.
As to the "polarity" of the dialog box, this is something which had a lot of internal debate. However, the complaint that "Users will unthinkingly make the secure chioce" isn't really a criticism from a security point of view.
As to the idea of creating an "Allow list of sites that don't use HTTPS properly"-- sure, you could do that, but users would likely (legitimately) wonder "Why don't I see a lock icon on this HTTPS site?" We know (from asking users) that they assume this is a browser bug, not a site problem. Opera chose to allow this insecurity but puts up a snarky "This page tried to use security measures, but failed" message which makes me laugh every time I see it.
Older versions of Chrome used to silently allow Mixed Content, putting the integrity of the page at risk without permission of the user. However, Chrome 2.0's Dev branch has a cool new feature, whereby they block executable content (e.g. script) by default and overlay all insecurely-delivered images with a "not secure" layer. It's a cool idea, and it will be interesting to see if the research community is able to poke holes in it.
Personally, I take the stance that "HTTPS should mean that this page was delivered securely" and thus I choose the "Disable mixed content" option. There's no sense locking the front door and leaving the window open.
I experienced an odd situation where the secure lock was not displayed but no warning was given either.
We were requesting a 3rd party image URL via an https://www..../..jpg and that was being redirected by the third party to http://www..../...jpg and served to us. So, the result was no security warning in the browser, but the page did not show the lock icon after that particular image loaded either. Sort of like a “silent mixed mode trigger”. As an aside, the browser did not block the content.
Be sure to inspect any third party references that are meant to be secure to make certain they are not returning standard http.
As noted in the article, Fiddler is very useful for detecting insecure redirections.
@eric: Thanks for the quick response!
I've set up a test page that exhibits the problem:
Some interesting things to note: If you run HTTPWatch or Fiddler, sometimes the error does not occur (which makes me wonder if it's something related to the SSL certs). If you run without either of these, it seems pretty consistent. I'm using IE 8.0.7100.0.
Any advice you can offer would be greatly appreciated!
Fascinating. This is a race condition.
The debugger reports that the following is the URL that is triggering the prompt:
Of course, that URL doesn't actually exist in your markup. It looks like there's dynamic creation of an IFRAME and injection of content into that frame. The default URL for an empty frame is about:blank, which leads to the prompt.
As a workaround, using an absolute URL would probably work, or by initializing the IFRAME with a the SRC of a blank page on your server (this should also fix the Mixed Content problem with IE6).
Thanks very much for looking at this. I'm not entirely sure why this particular URL is relative, but it definitely gives us a much better idea of where to look.
>If a major site isn't using HTTPS properly, blame should properly accrue to that site, and the site should be fixed.
I read this blog post after spending countless hours with end users who were experiencing an issue with web content we create. However, our firm does not have direct access to the secure server. Instead, we leverage that server to distribute our own content to end users. So while the above sentiment would be nice in an ideal world, the current world is not always ideal.
What bothers me the most about the change to IE's security warning -- apart from the fact that it has single-handedly cost us significantly in terms of recent help ticket resolution -- is this:
1. There was no vetting or advanced notice of the change to IT firms or the IE community at large...no way to prepare or even be aware of the chagne in advance. It was actually quite difficult to even find this blog post after the issue was identified by our team.
2. It takes an existing process (clicking "Yes" when the user visits the same web site he or she has been visiting successfully for the last 6 or more years) and inverts it. For many users, clicking "Yes" on the previous security warning had slowly come to mean "Yes, show me the damn page already!" Now the process of "agreeing" with IE with an affirmative response was breaking the website. In the very least, the first time the new browser had this instance, it should have delivered the message in a different way -- other than a too-familiar dialog box method -- that the question polarity had changed. Or add the explanation, "If you are visiting a familiar website and are unable to see all the content, consider answering the security question differently."
As it is, my department now has literally hundreds of users to educate on the polarity difference and retrain a behavior that has become ingrained over the last few years -- all due to the whim of a dialog box and the programmers that made it. We would love to just abandon IE in favor of another browser, but sadly that is not always an option for some of our constituents.
As an aside, is there a way to reference content so that if my connection is over HTTPS, the external references will be called via HTTPS as well?
@Chris asked: "is there a way to reference content..."
Indeed, that's the subject of the second paragraph in the section "Preventing Mixed Content Warnings (for web developers)." Use a protocol-relative hyperlink.
@Chris opined: "There was no vetting or advanced notice of the change to IT firms or the IE community at large..."
Actually, that's not true. We have a Beta program for a reason.
New browser versions have tens of thousands of changes, and there are hundreds of millions of browser users. As you might imagine, such scale prevents one-on-one walkthroughs of every change with every developer.
I have installed Fiddler and tested it with my site that seems to give this problem - all protocol requests shows HTTP and not HTTPS...
I then tested this with my bank's online banking and this has the same result in Fiddler... it just shows HTTP for everything.
On my site I get the IE 8 warning, but not on the bank's site - so I'm fairly confident that the bank's site is secure, but fiddler isn't really helping me out though!
@Sam: If you want to see HTTPS requests in Fiddler, you have to turn on HTTPS decryption (see the Help). Otherwise, you'll only see the HTTP CONNECT tunnels through which secure traffic flows.
If you see any HTTP request which is NOT a CONNECT tunnel while visiting a secure site, that's a Mixed Content bug.
If your site is public, I'd be happy to have a look.