We are all familiar with the problem of mixed scheme (http / https) content on a page.
I'm working on a site on which this is unavoidable. I do not want to prevent this. I know there are a ton of questions / answers on that.
What I need is simply to detect this (via JavaScript?) so I can tweak the page behavior (show a notice of degraded behavior or something). Any help?
Using jQuery you can find out if any insecure items are present on a page using the following piece of code:
var flag = false;
if($("script[src^='http:']").length > 0
|| $("link[type='text/css'][href^='http:']").length > 0
|| $("img[src^='http:']").length > 0
|| $("iframe[src^=http:]").length > 0)
flag = true; // insecure content :(
else
// yay!
Images, JS, CSS are all the insecure content that I could think of. Perhaps there are more, but you could easily add'em up as you find.
It's hacky, but I managed to fix this in all browsers with just JavaScript. Let me see if I can sketch it out.
We have this basic encrypted page:
<html>
<body>
<div> stuff </div>
<iframe src="URL_WHICH_IS_MAYBE_INSECURE"></iframe>
</body>
</html>
When URL_WHICH_IS_MAYBE_INSECURE
is https, all is good. But when URL_WHICH_IS_MAYBE_INSECURE
is http, IE will not load the content unless the user OK's insecure/mixed content. I want to tell the user the page is kinda busted until they click allow. For reasons I can't go into, I know all the sites are trustworthy. Just some of them do not support SSL and the parent site needs to.
AFAIK, I cannot detect this dialog / semi-loaded state with JS. But what I can do is run JS over an insecure connection IF they allow it (which also makes the iframe go). So only when URL_WHICH_IS_MAYBE_INSECURE
is http & the site is https (mixed) I add two bits of code + HTML.
<html>
<body>
<div> stuff </div>
@if(needSpecialHandlingForMixedMode) {
<div id="secureWarn">
WARNING: This page has limited functionality, allow mixed content
</div>
}
<iframe src="URL_WHICH_IS_MAYBE_INSECURE"></iframe>
</body>
@if (needSpecialHandlingForMixedMode)
{
string baseUrl = Request.Url.SchemeAndHostAndPort().Replace("https", "http");
<script src="@baseUrl/scripts/security-warning.js"></script>
}
</html>
and the script is
$(document).ready(function(e) {
$("#secureWarn").remove();
});
So it works like this.
- If mixed-mode both the iframe and script will only load if the user allows it. This is not allowed by default in IE and is allowed by default in Chrome & FireFox.
- If they do nothing (don't allow in IE, for example), it will keep the warning div visible.
- If they do click it, the iframe loads, and now the script also runs (because it was insecure back to my server), this removes the warning from the page.
- Happiness commences...
Hope this helps someone.
Cheers,
Michael