| Index: Source/core/loader/MixedContentChecker.cpp
|
| diff --git a/Source/core/loader/MixedContentChecker.cpp b/Source/core/loader/MixedContentChecker.cpp
|
| index b36d8b25f03af2c802e2e09b84a75b1284b45352..673903cf8d8f7ef03af7288c3723d026b8b8f71c 100644
|
| --- a/Source/core/loader/MixedContentChecker.cpp
|
| +++ b/Source/core/loader/MixedContentChecker.cpp
|
| @@ -81,6 +81,34 @@ bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K
|
| }
|
|
|
| // static
|
| +LocalFrame* MixedContentChecker::inWhichFrameIsContentMixed(LocalFrame* frame, WebURLRequest::FrameType frameType, const KURL& url)
|
| +{
|
| + // We only care about subresource loads; top-level navigations cannot be mixed content. Neither can frameless requests.
|
| + if (frameType == WebURLRequest::FrameTypeTopLevel || !frame)
|
| + return nullptr;
|
| +
|
| + // Check the top frame first.
|
| + if (Frame* top = frame->tree().top()) {
|
| + // FIXME: We need a way to access the top-level frame's SecurityOrigin when that frame
|
| + // is in a different process from the current frame. Until that is done, we bail out.
|
| + if (!top->isLocalFrame())
|
| + return nullptr;
|
| +
|
| + LocalFrame* localTop = toLocalFrame(top);
|
| + measureStricterVersionOfIsMixedContent(localTop, url);
|
| + if (isMixedContent(localTop->document()->securityOrigin(), url))
|
| + return localTop;
|
| + }
|
| +
|
| + measureStricterVersionOfIsMixedContent(frame, url);
|
| + if (isMixedContent(frame->document()->securityOrigin(), url))
|
| + return frame;
|
| +
|
| + // No mixed content, no problem.
|
| + return nullptr;
|
| +}
|
| +
|
| +// static
|
| MixedContentChecker::ContextType MixedContentChecker::contextTypeFromContext(WebURLRequest::RequestContext context)
|
| {
|
| switch (context) {
|
| @@ -271,42 +299,20 @@ void MixedContentChecker::count(LocalFrame* frame, WebURLRequest::RequestContext
|
| // static
|
| bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus)
|
| {
|
| - // No frame, no mixed content:
|
| - if (!frame)
|
| + LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, frameType, url);
|
| + if (!mixedFrame)
|
| return false;
|
|
|
| - // Check the top frame first.
|
| - if (Frame* top = frame->tree().top()) {
|
| - // FIXME: We need a way to access the top-level frame's SecurityOrigin when that frame
|
| - // is in a different process from the current frame. Until that is done, we bail out
|
| - // early and allow the load.
|
| - if (!top->isLocalFrame())
|
| - return false;
|
| -
|
| - LocalFrame* localTop = toLocalFrame(top);
|
| - if (frame != localTop && shouldBlockFetch(localTop, requestContext, frameType, url, reportingStatus))
|
| - return true;
|
| - }
|
| + MixedContentChecker::count(mixedFrame, requestContext);
|
|
|
| - // We only care about subresource loads; top-level navigations cannot be mixed content.
|
| - if (frameType == WebURLRequest::FrameTypeTopLevel)
|
| - return false;
|
| -
|
| - // No mixed content, no problem.
|
| - measureStricterVersionOfIsMixedContent(frame, url);
|
| - if (!isMixedContent(frame->document()->securityOrigin(), url))
|
| - return false;
|
| -
|
| - MixedContentChecker::count(frame, requestContext);
|
| -
|
| - Settings* settings = frame->settings();
|
| - FrameLoaderClient* client = frame->loader().client();
|
| - SecurityOrigin* securityOrigin = frame->document()->securityOrigin();
|
| + Settings* settings = mixedFrame->settings();
|
| + FrameLoaderClient* client = mixedFrame->loader().client();
|
| + SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin();
|
| bool allowed = false;
|
|
|
| // If we're in strict mode, we'll automagically fail everything, and intentionally skip
|
| // the client checks in order to prevent degrading the site's security UI.
|
| - bool strictMode = frame->document()->shouldEnforceStrictMixedContentChecking() || settings->strictMixedContentChecking();
|
| + bool strictMode = mixedFrame->document()->shouldEnforceStrictMixedContentChecking() || settings->strictMixedContentChecking();
|
|
|
| ContextType contextType = contextTypeFromContext(requestContext);
|
|
|
| @@ -343,74 +349,69 @@ bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::Req
|
| return !allowed;
|
| }
|
|
|
| -bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, const KURL& url, const MixedContentType type) const
|
| +// static
|
| +bool MixedContentChecker::shouldBlockConnection(LocalFrame* frame, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus)
|
| {
|
| - // Check the top frame if it differs from MixedContentChecker's m_frame.
|
| - if (!m_frame->tree().top()->isLocalFrame()) {
|
| - // FIXME: We need a way to access the top-level frame's MixedContentChecker when that frame
|
| - // is in a different process from the current frame. Until that is done, we always allow
|
| - // loads in remote frames.
|
| - return false;
|
| - }
|
| - Frame* top = m_frame->tree().top();
|
| - if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->canDisplayInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url, type))
|
| + LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url);
|
| + if (!mixedFrame)
|
| return false;
|
|
|
| - // Just count these for the moment, don't block them.
|
| - if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->isReservedIPAddress(KURL(ParsedURLString, securityOrigin->toString())))
|
| - UseCounter::count(m_frame->document(), UseCounter::MixedContentPrivateIPInPublicWebsitePassive);
|
| -
|
| - // Then check the current frame:
|
| - if (!isMixedContent(securityOrigin, url))
|
| - return true;
|
| -
|
| - Settings* settings = m_frame->settings();
|
| - bool allowed = client()->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url);
|
| - logWarning(allowed, url, type);
|
| + UseCounter::count(mixedFrame, UseCounter::MixedContentPresent);
|
| + UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket);
|
|
|
| - if (allowed)
|
| - client()->didDisplayInsecureContent();
|
| + // If we're in strict mode, we'll automagically fail everything, and intentionally skip
|
| + // the client checks in order to prevent degrading the site's security UI.
|
| + bool strictMode = mixedFrame->document()->shouldEnforceStrictMixedContentChecking();
|
| +
|
| + Settings* settings = mixedFrame->settings();
|
| + FrameLoaderClient* client = mixedFrame->loader().client();
|
| + SecurityOrigin* securityOrigin = mixedFrame->document()->securityOrigin();
|
| + bool allowedPerSettings = settings && (settings->allowRunningOfInsecureContent() || settings->allowConnectingInsecureWebSocket());
|
| + bool allowed = !strictMode && client->allowRunningInsecureContent(allowedPerSettings, securityOrigin, url);
|
| +
|
| + if (reportingStatus == SendReport) {
|
| + String message = String::format(
|
| + "Mixed Content: The page at '%s' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint '%s'. %s",
|
| + frame->document()->url().elidedString().utf8().data(), url.elidedString().utf8().data(),
|
| + allowed ? "This endpoint should be available via WSS. Insecure access is deprecated." : "This request has been blocked; this endpoint must be available over WSS.");
|
| + MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel;
|
| + mixedFrame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, messageLevel, message));
|
| + }
|
|
|
| - return allowed;
|
| + return !allowed;
|
| }
|
|
|
| -bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin, const KURL& url, const MixedContentType type) const
|
| +bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, const KURL& url, const MixedContentType type) const
|
| {
|
| // Check the top frame if it differs from MixedContentChecker's m_frame.
|
| if (!m_frame->tree().top()->isLocalFrame()) {
|
| // FIXME: We need a way to access the top-level frame's MixedContentChecker when that frame
|
| // is in a different process from the current frame. Until that is done, we always allow
|
| // loads in remote frames.
|
| - return true;
|
| + return false;
|
| }
|
| Frame* top = m_frame->tree().top();
|
| - if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->canRunInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url, type))
|
| + if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->canDisplayInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url, type))
|
| return false;
|
|
|
| // Just count these for the moment, don't block them.
|
| if (Platform::current()->isReservedIPAddress(url) && !Platform::current()->isReservedIPAddress(KURL(ParsedURLString, securityOrigin->toString())))
|
| - UseCounter::count(m_frame->document(), UseCounter::MixedContentPrivateIPInPublicWebsiteActive);
|
| + UseCounter::count(m_frame->document(), UseCounter::MixedContentPrivateIPInPublicWebsitePassive);
|
|
|
| // Then check the current frame:
|
| if (!isMixedContent(securityOrigin, url))
|
| return true;
|
|
|
| Settings* settings = m_frame->settings();
|
| - bool allowedPerSettings = settings && (settings->allowRunningOfInsecureContent() || ((type == WebSocket) && settings->allowConnectingInsecureWebSocket()));
|
| - bool allowed = client()->allowRunningInsecureContent(allowedPerSettings, securityOrigin, url);
|
| + bool allowed = client()->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url);
|
| logWarning(allowed, url, type);
|
|
|
| if (allowed)
|
| - client()->didRunInsecureContent(securityOrigin, url);
|
| + client()->didDisplayInsecureContent();
|
|
|
| return allowed;
|
| }
|
|
|
| -bool MixedContentChecker::canConnectInsecureWebSocket(SecurityOrigin* securityOrigin, const KURL& url) const
|
| -{
|
| - return canRunInsecureContent(securityOrigin, url, MixedContentChecker::WebSocket);
|
| -}
|
| -
|
| bool MixedContentChecker::canSubmitToInsecureForm(SecurityOrigin* securityOrigin, const KURL& url) const
|
| {
|
| // For whatever reason, some folks handle forms via JavaScript, and submit to `javascript:void(0)`
|
|
|