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!
@Naveen-- if changing a http link to a protocol relative link didn't get rid of the message, that simply means that you have other HTTP links still in the page. If you use IE9 or another browser, you can easily find them by opening the developer tools. Or you can email me the URL of the site and I'll help you find it.
I've tried to find the answer to a problem I suddenly found myself having today, but couldn't: If I've (by mistake or otherwise) clicked either yes or no for a particular page, but really wanted the opposite, is there any way to get the question again? We're running XP here, if that is of any importance.
@Martin: I'm not sure I understand the question. If you close and restart the browser, your choice in the "Allow mixed content" prompt is reset.
That's OK, I'm not sure I'm phrasing it correctly.
As I currently don't get the question, I'm not able to be too precise. The first time I visited the mixed content (unfortunately not publicly available) in question, I was prompted as to whether I wanted to view only the secure content or not. I answered with "No", and got to see all the content. I then wanted to test the page using "Yes", but I can't trigger the prompt again. Restarting the browser doesn't trigger it, neither does emptying the cache or restarting the whole computer. My answer seem to be cached and remembered somewhere.
Judging from your response, this is not how the answer to that prompt is normally handled?
@Martin: Correct, there's no persistent cache of that decision. It's possible that you hit a timing-related race condition (bug). You might try deleting your browser history (cookies and temp files) and then try loading the page again.
Some kind of race condition does seem plausible, as the page is a bit complex, mixing protocols and servers in various ways.
For some reason, I got the prompt again today, once. Once was all I needed for the testing.
Thanks for your time and effort!
@EricLaw - Are there ANY solutions for the src of an iframe in IE6 to avoid this warning dialog if there is no desired source?
e.g. Often iframes are use in IE6 as a shim to insert under floated content to overcome the IE6 z-index bug. [[ webbugtrack.blogspot.com/.../bug-111-ie-broke-web-20.html ]] The iframe needs no actual source and we don't want to add another hit to our server (for each and every iframe we use) for a dummy file.
Unfortunately as you've noted above, we can't use "about:blank" because that triggers the warning in IE6 (a major bug in the implementation IMHO) and we can't leave the src attribute blank, or exclude it because the default is "about:blank"!!!! (adding insult to injury!)
Are there any other options (even if un-sanctioned, un-endorsed, back-door-trickery) to avoid this warning?
e.g. does the old "gopher:" or "ftp:" scheme trip up the warning?
or would a reference to the already requested ROOT/favicon.ico file cause the warning to go away? e.g. <iframe src="/favicon.ico">? Or would this work... but show the image in the frame if the iframe's content is visible (e.g. if used as a shim, would it hide the icon and skip the warning?)
What about the old "about:mozilla"? or is the whole "about:" scheme considered insecure across the board?
I kind of wish there was a "null:" or "noop:" scheme now just to avoid all this mess.
Gah, I just thought about this... if I have/use a custom protocol, e.g. "icq:12345678"... but there is no "handler" registered for this protocol,... will this work or is IE going to popup the "unknown protocol/handler" dialog now instead?
@Gary: I think that by-far your best bet for the dwindling number of IE6 users is to point to a dummy blank page on your server, served via HTTPS. You can set the headers on the page such that it's stored in the user's cache and not redownloaded from the server, so you'd see a max of one additional hit per user.
Regarding the mixed content problem, Would you mind looking at
and help me understand what I'm doing wrong?
@Steve: You've hit the same problem that many folks seem to be hitting; there's a race condition where a relative URL is combined with the "about" protocol and is being deemed insecure.
SEC7111: HTTPS security is compromised by about:Content2Background.png
SEC7111: HTTPS security is compromised by about:ShowsPhoto.PNG
Are you using the latest version of any script libraries you're using? I assume your code creates a new frame at "about:blank" and injects content into that?
We have a little different problem than the others here.
We want the webshop on our site to be under https, everything is working fine but we get the mixed content warning and I can see (using httpWatch or you scriptfreesetup.exe) that it is the
that generates the warning.
In httpWatch I can see that these files are first called with https but are then redirected to http.
Any idea on this? I've been at it for weeks now and I am no closer to a solution.
I'm getting really desperate and would appriciate any help or hints at all.
Unfortunally I can't give you a link since it is on our test servers.
@Andreas: I'm not sure what you're asking. If the server is redirecting from HTTPS to HTTP, you'll need to prevent that.
Eric: Would you please look at my website as well (url removed)? I am not sure what is causing the mixed content problem. Please advise. With Thanks!
@Sam: If you're referring to the warning on the page when you click the misspelled "Earings" link-- the mixed content appears to be caused by the malicious content that has been injected into your page. So either you're a bad guy (I hope not) or someone else has stolen your password and is trying to use your server to spread malware.
Search your page's source for the word "unescape" to see the malicious content.
Eric: Here's a stumper for you... harmony.request.com/.../scott.asp
The page pulls in draw2d.js (http://www.draw2d.org). Fiddler, Httpwatch, and Firebug (on Firefox) all report NO unsecure HTTP traffic. There is no indication of any removeChild for elements with a background. We're not even asking the classes for any objects, just the mere loading of the classes is triggering the mixed content warning in IE8. It may be the programmatic addition of a form button via DOM or some other item, but my team of engineers is stumped.