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!
@Berrisford: The problem you're describing is unrelated to the mixed-content issue. The problem you're encountering is caused by the "Cache-Control: no-cache" response header sent with the HTTPS-delivered image.
That header prevents persistent caching of the HTTPS image, and that, in turn, prevents proper saving of the image from the HTML page.
Incidentally, this is the same root cause of the related problem where, if you right-click on that image, only the Bitmap file type is available as a Save As choice. The image cannot be saved in .JPG format because it's not in the cache; Trident only has the in-memory bitmap available to re-save.
How could we ever leave an https section of the site to move back to an http section of the site if we can't include a link to the http section from the https page without generating a mixed content warning?
@Odinhaus: Including an <A> tag with an HREF to a non-HTTPS site will not trigger a mixed content warning. Only if you include a tag that performs a download (e.g. SCRIPT, IMG, LINK, @import, etc) will the URL be checked to verify that the protocol is secure.
Hi Eric, I´m reading this and hoping you can help me. We´re having simmilar problems. In FF everything looks fine, but in IE 7/8 we get a ´unsecure items´ error.
I really cannot find what is causing this. I tried httpwatch, fiddler and your script (but that is not working with me, IE crashes).
I was wondering if you could take a look? It would be great.
If you take out the SRC, you won’t have this problem.
I have this problem on my site. I know it is being caused by an ad.doubleclick URL which is happening over HTTP. But I cant locate this in the code.
Do you have any thoughts on this.
Thanks already since your post here was very informative.
@Nachiket: If you post the URL of your site, I can easily tell you where the insecure request is coming from.
The simplest way to find an insecure HTTP reference is to clear your cache, run Fiddler, capture the complete load of your site, hit CTRL+F, tick the "Decode Compressed Content" box, and then type in the hostname of the insecure reference in the Find box.
I looked closely with fiddler and do not see any http content being delivered to our secure page.
Perhaps you could take a peek at this url and let me know what I'm missing?
@Jason, you have exactly the same problem as Rene above.
Contains this text:
Remove the SRC attribute and your problem goes away.
Can you think of another solution either to determining when the DOM is ready or to hiding this errant error message?
BTW, thanks for pointing out the mimetype problem. Will investigate.
@Jason: To be clear, IE doesn't "ignore" the event-- it simply doesn't implement this nonstandard event that was added by Gecko.
The DEFER attribute on the SCRIPT tag already does what you're trying to do.
The alternative is to attach an event to the ONLOAD event of the BODY element.
I have the mixed problem in a site when deploy in a secure server.
My menu images all use full URL addresses as do the images in the footer yet, when I check them in fiddler they appear without the http://.
I can't say how much revenue I have lost since IE8 came out but, I know that is is a lot. It would be nice if at the very least images were excluded from this security function since images do not offer a security risk.
Thanks for this info!
@Ralph: I'm not sure I understand you. IE is working exactly as designed in this case; if you want your page to work properly, you need to remove the insecure references. That includes your images, and your insecure reference to addthis_widget.js which compromises the whole page.
<<I can't say how much revenue I have lost since IE8 came out but, I know that is is a lot>>
IE5/6 and 7 blocked insecure content as well. Is there some reason you didn't fix your page a decade ago?
<<images do not offer a security risk.>>
I'm not sure how you arrived at that conclusion, but you're mistaken. It's true that images cannot be used to steal content from the page, but they can leak your cookies and they can modify the page with misleading instructions (E.g. Telephone your credit card # to <evil phone number>)