bool MixedContentChecker::isMixedFormAction(LocalFrame* frame, const KURL& url, ReportingStatus reportingStatus) { // For whatever reason, some folks handle forms via JavaScript, and submit to `javascript:void(0)` // rather than calling `preventDefault()`. We special-case `javascript:` URLs here, as they don't // introduce MixedContent for form submissions. if (url.protocolIs("javascript")) return false; Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); if (!mixedFrame) return false; UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); // Use the current local frame's client; the embedder doesn't // distinguish mixed content signals from different frames on the // same page. frame->loader().client()->didDisplayInsecureContent(); if (reportingStatus == SendReport) { String message = String::format( "Mixed Content: The page at '%s' was loaded over a secure connection, but contains a form which targets an insecure endpoint '%s'. This endpoint should be made available over a secure connection.", mainResourceUrlForFrame(mixedFrame).elidedString().utf8().data(), url.elidedString().utf8().data()); frame->document()->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, WarningMessageLevel, message)); } return true; }
// static bool MixedContentChecker::shouldBlockWebSocket(LocalFrame* frame, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) { Frame* mixedFrame = inWhichFrameIsContentMixed(frame, WebURLRequest::FrameTypeNone, url); if (!mixedFrame) return false; UseCounter::count(mixedFrame, UseCounter::MixedContentPresent); UseCounter::count(mixedFrame, UseCounter::MixedContentWebSocket); 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(); if (!strictMode) { bool allowedPerSettings = settings && settings->allowRunningOfInsecureContent(); allowed = client->allowRunningInsecureContent(allowedPerSettings, securityOrigin, url); } if (allowed) client->didRunInsecureContent(securityOrigin, url); if (reportingStatus == SendReport) logToConsoleAboutWebSocket(frame, mainResourceUrlForFrame(mixedFrame), url, allowed); return !allowed; }
WebMixedContent::ContextType MixedContentChecker::contextTypeForInspector( LocalFrame* frame, const ResourceRequest& request) { Frame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType()); Frame* mixedFrame = inWhichFrameIsContentMixed( effectiveFrame, request.frameType(), request.url()); if (!mixedFrame) return WebMixedContent::ContextType::NotMixedContent; // See comment in shouldBlockFetch() about loading the main resource of a // subframe. if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled( request.url().protocol())) { return WebMixedContent::ContextType::OptionallyBlockable; } bool strictMixedContentCheckingForPlugin = mixedFrame->settings() && mixedFrame->settings()->strictMixedContentCheckingForPlugin(); return WebMixedContent::contextTypeFromRequestContext( request.requestContext(), strictMixedContentCheckingForPlugin); }
MixedContentChecker::ContextType MixedContentChecker::contextTypeForInspector(LocalFrame* frame, const ResourceRequest& request) { Frame* effectiveFrame = effectiveFrameForFrameType(frame, request.frameType()); Frame* mixedFrame = inWhichFrameIsContentMixed(effectiveFrame, request.frameType(), request.url()); if (!mixedFrame) return ContextTypeNotMixedContent; // See comment in shouldBlockFetch() about loading the main resource of a subframe. if (request.frameType() == WebURLRequest::FrameTypeNested && !SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { return ContextTypeOptionallyBlockable; } return contextTypeFromContext(request.requestContext(), mixedFrame); }
// 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; }
// static bool MixedContentChecker::shouldBlockFetch(LocalFrame* frame, WebURLRequest::RequestContext requestContext, WebURLRequest::FrameType frameType, const KURL& url, MixedContentChecker::ReportingStatus reportingStatus) { LocalFrame* mixedFrame = inWhichFrameIsContentMixed(frame, frameType, url); if (!mixedFrame) return false; MixedContentChecker::count(mixedFrame, requestContext); 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 = 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 in subframes, unless all insecure // content is allowed. if (!settings->allowRunningOfInsecureContent() && requestIsSubframeSubresource(frame, frameType)) { 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, url, requestContext, allowed); return !allowed; }