// 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; }
bool MixedContentChecker::canRunInsecureContentInternal(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 false; } Frame* top = m_frame->tree().top(); if (top != m_frame && !toLocalFrame(top)->loader().mixedContentChecker()->canRunInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url)) return false; // 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); logWarning(allowed, url, type); if (allowed) client()->didRunInsecureContent(securityOrigin, url); return allowed; }
// static Frame* MixedContentChecker::inWhichFrameIsContentMixed(Frame* 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()) { measureStricterVersionOfIsMixedContent(top, url); if (isMixedContent(top->securityContext()->getSecurityOrigin(), url)) return top; } measureStricterVersionOfIsMixedContent(frame, url); if (isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) return frame; // No mixed content, no problem. return nullptr; }
bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin, const URL& url) const { if (!isMixedContent(securityOrigin, url)) return true; bool allowed = client().allowRunningInsecureContent(m_frame->settings().allowRunningOfInsecureContent(), securityOrigin, url); logWarning(allowed, "ran", url); if (allowed) client().didRunInsecureContent(securityOrigin, url); return allowed; }
bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, const URL& url) const { if (!isMixedContent(securityOrigin, url)) return true; bool allowed = client().allowDisplayingInsecureContent(m_frame->settings().allowDisplayOfInsecureContent(), securityOrigin, url); logWarning(allowed, "displayed", url); if (allowed) client().didDisplayInsecureContent(); return allowed; }
bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, ContentType type, const URL& url) const { if (!isMixedContent(securityOrigin, url)) return true; bool allowed = m_frame.settings().allowDisplayOfInsecureContent() || type == ContentType::ActiveCanWarn; logWarning(allowed, "display", url); if (allowed) client().didDisplayInsecureContent(); return allowed; }
void MixedContentChecker::checkFormForMixedContent(SecurityOrigin* securityOrigin, const URL& url) const { // Unconditionally allow javascript: URLs as form actions as some pages do this and it does not introduce // a mixed content issue. if (protocolIsJavaScript(url)) return; if (!isMixedContent(securityOrigin, url)) return; String message = makeString("The page at ", m_frame.document()->url().stringCenterEllipsizedToLength(), " contains a form which targets an insecure URL ", url.stringCenterEllipsizedToLength(), ".\n"); m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, message); client().didDisplayInsecureContent(); }
// static bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) { Frame* effectiveFrame = effectiveFrameForFrameType(frame, frameType); Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, frameType, url); if (!mixedFrame) return false; MixedContentChecker::count(mixedFrame, requestContext); Settings* settings = mixedFrame->settings(); // Use the current local frame's client; the embedder doesn't // distinguish mixed content signals from different frames on the // same page. FrameLoaderClient* client = frame->loader().client(); SecurityOrigin* securityOrigin = mixedFrame->securityContext()->getSecurityOrigin(); 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 = mixedFrame->securityContext()->shouldEnforceStrictMixedContentChecking() || settings->strictMixedContentChecking(); ContextType contextType = contextTypeFromContext(requestContext, mixedFrame); // If we're loading the main resource of a subframe, we need to take a close look at the loaded URL. // If we're dealing with a CORS-enabled scheme, then block mixed frames as active content. Otherwise, // treat frames as passive content. // // FIXME: Remove this temporary hack once we have a reasonable API for launching external applications // via URLs. http://crbug.com/318788 and https://crbug.com/393481 if (frameType == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(url.protocol())) contextType = ContextTypeOptionallyBlockable; switch (contextType) { case ContextTypeOptionallyBlockable: allowed = !strictMode && client->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), url); if (allowed) client->didDisplayInsecureContent(); break; case ContextTypeBlockable: { // Strictly block subresources that are mixed with respect to // their subframes, unless all insecure content is allowed. This // is to avoid the following situation: https://a.com embeds // https://b.com, which loads a script over insecure HTTP. The // user opts to allow the insecure content, thinking that they are // allowing an insecure script to run on https://a.com and not // realizing that they are in fact allowing an insecure script on // https://b.com. if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubresource(effectiveFrame, frameType) && isMixedContent(frame->securityContext()->getSecurityOrigin(), url)) { UseCounter::count(mixedFrame, UseCounter::BlockableMixedContentInSubframeBlocked); allowed = false; break; } bool shouldAskEmbedder = !strictMode && settings && (!settings->strictlyBlockBlockableMixedContent() || settings->allowRunningOfInsecureContent()); allowed = shouldAskEmbedder && client->allowRunningInsecureContent(settings && settings->allowRunningOfInsecureContent(), securityOrigin, url); if (allowed) { client->didRunInsecureContent(securityOrigin, url); UseCounter::count(mixedFrame, UseCounter::MixedContentBlockableAllowed); } break; } case ContextTypeShouldBeBlockable: allowed = !strictMode; if (allowed) client->didDisplayInsecureContent(); break; case ContextTypeNotMixedContent: ASSERT_NOT_REACHED(); break; }; if (reportingStatus == SendReport) logToConsoleAboutFetch(frame, mainResourceUrlForFrame(mixedFrame), url, requestContext, allowed); return !allowed; }