Bug 1182551 - Don't set STATE_IS_BROKEN on HTTP pages when mixed content is allowed by default. r=smaug

This commit is contained in:
Tanvi Vyas 2015-08-13 17:13:43 -07:00
parent ef72e23c1f
commit 9254729572

View File

@ -55,8 +55,8 @@ bool nsMixedContentBlocker::sBlockMixedDisplay = false;
class nsMixedContentEvent : public nsRunnable
{
public:
nsMixedContentEvent(nsISupports *aContext, MixedContentTypes aType)
: mContext(aContext), mType(aType)
nsMixedContentEvent(nsISupports *aContext, MixedContentTypes aType, bool aRootHasSecureConnection)
: mContext(aContext), mType(aType), mRootHasSecureConnection(aRootHasSecureConnection)
{}
NS_IMETHOD Run()
@ -85,6 +85,21 @@ public:
nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
// Get eventSink and the current security state from the docShell
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
NS_ASSERTION(eventSink, "No eventSink from docShell.");
nsCOMPtr<nsIDocShell> rootShell = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootShell, "No root docshell from document shell root tree item.");
uint32_t state = nsIWebProgressListener::STATE_IS_BROKEN;
nsCOMPtr<nsISecureBrowserUI> securityUI;
rootShell->GetSecurityUI(getter_AddRefs(securityUI));
// If there is no securityUI, document doesn't have a security state to
// update. But we still want to set the document flags, so we don't return
// early.
nsresult stateRV;
if (securityUI) {
stateRV = securityUI->GetState(&state);
}
if (mType == eMixedScript) {
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
@ -94,18 +109,26 @@ public:
rootDoc->SetHasMixedActiveContentLoaded(true);
// Update the security UI in the tab with the allowed mixed active content
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
// If mixed display content is loaded, make sure to include that in the state.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
if (securityUI) {
// Bug 1182551 - before changing the security state to broken, check
// that the root is actually secure.
if (mRootHasSecureConnection) {
// If mixed display content is loaded, make sure to include that in the state.
if (rootDoc->GetHasMixedDisplayContentLoaded()) {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
} else {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
} else {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
// root not secure, mixed active content loaded in an https subframe
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(mContext, (state | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
}
}
@ -117,17 +140,25 @@ public:
rootDoc->SetHasMixedDisplayContentLoaded(true);
// Update the security UI in the tab with the allowed mixed display content.
nsCOMPtr<nsISecurityEventSink> eventSink = do_QueryInterface(docShell);
if (eventSink) {
if (securityUI) {
// Bug 1182551 - before changing the security state to broken, check
// that the root is actually secure.
if (mRootHasSecureConnection) {
// If mixed active content is loaded, make sure to include that in the state.
if (rootDoc->GetHasMixedActiveContentLoaded()) {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
if (rootDoc->GetHasMixedActiveContentLoaded()) {
eventSink->OnSecurityChange(mContext,
(nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
} else {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
} else {
eventSink->OnSecurityChange(mContext, (nsIWebProgressListener::STATE_IS_BROKEN |
nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
// root not secure, mixed display content loaded in an https subframe
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(mContext, (state | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
}
}
}
@ -141,6 +172,9 @@ private:
// The type of mixed content detected, e.g. active or display
const MixedContentTypes mType;
// Indicates whether the top level load is https or not.
bool mRootHasSecureConnection;
};
@ -673,7 +707,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
NS_ASSERTION(eventSink, "No eventSink from docShell.");
nsCOMPtr<nsIDocShell> rootShell = do_GetInterface(sameTypeRoot);
NS_ASSERTION(rootShell, "No root docshell from document shell root tree item.");
uint32_t State = nsIWebProgressListener::STATE_IS_BROKEN;
uint32_t state = nsIWebProgressListener::STATE_IS_BROKEN;
nsCOMPtr<nsISecureBrowserUI> securityUI;
rootShell->GetSecurityUI(getter_AddRefs(securityUI));
// If there is no securityUI, document doesn't have a security state.
@ -682,7 +716,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
*aDecision = nsIContentPolicy::ACCEPT;
return NS_OK;
}
nsresult stateRV = securityUI->GetState(&State);
nsresult stateRV = securityUI->GetState(&state);
// If the content is display content, and the pref says display content should be blocked, block it.
if (sBlockMixedDisplay && classification == eMixedDisplay) {
@ -712,7 +746,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// User has overriden the pref and the root is not https;
// mixed display content was allowed on an https subframe.
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (state | nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT));
}
}
} else {
@ -720,7 +754,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked);
if (!rootDoc->GetHasMixedDisplayContentBlocked() && NS_SUCCEEDED(stateRV)) {
rootDoc->SetHasMixedDisplayContentBlocked(true);
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (state | nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT));
}
}
return NS_OK;
@ -755,7 +789,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// User has already overriden the pref and the root is not https;
// mixed active content was allowed on an https subframe.
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (state | nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
}
@ -772,7 +806,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// The user has not overriden the pref, so make sure they still have an option by calling eventSink
// which will invoke the doorhanger
if (NS_SUCCEEDED(stateRV)) {
eventSink->OnSecurityChange(aRequestingContext, (State | nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT));
eventSink->OnSecurityChange(aRequestingContext, (state | nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT));
}
return NS_OK;
}
@ -786,7 +820,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// Fire the event from a script runner as it is unsafe to run script
// from within ShouldLoad
nsContentUtils::AddScriptRunner(
new nsMixedContentEvent(aRequestingContext, classification));
new nsMixedContentEvent(aRequestingContext, classification, rootHasSecureConnection));
*aDecision = ACCEPT;
return NS_OK;
}