Index: third_party/WebKit/Source/core/loader/FrameLoader.cpp |
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
index 2cc064c10be47c272b6f42a4640d521b742781a2..f6eec468d0b8b394ae4e173e05a9e66a1e18ce89 100644 |
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
@@ -201,7 +201,7 @@ void FrameLoader::init() |
initialRequest.setRequestContext(WebURLRequest::RequestContextInternal); |
initialRequest.setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
m_provisionalDocumentLoader = client()->createDocumentLoader(m_frame, initialRequest, SubstituteData()); |
- m_provisionalDocumentLoader->startLoadingMainResource(CheckContentSecurityPolicy); |
+ m_provisionalDocumentLoader->startLoadingMainResource(); |
m_frame->document()->cancelParsing(); |
m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument); |
takeObjectSnapshot(); |
@@ -1358,14 +1358,30 @@ bool FrameLoader::shouldClose(bool isReload) |
} |
bool FrameLoader::shouldContinueForNavigationPolicy(const ResourceRequest& request, const SubstituteData& substituteData, |
- DocumentLoader* loader, NavigationType type, NavigationPolicy policy, bool replacesCurrentHistoryItem, bool isClientRedirect) |
+ DocumentLoader* loader, ContentSecurityPolicyDisposition shouldCheckMainWorldContentSecurityPolicy, |
+ NavigationType type, NavigationPolicy policy, bool replacesCurrentHistoryItem, bool isClientRedirect) |
{ |
// Don't ask if we are loading an empty URL. |
if (request.url().isEmpty() || substituteData.isValid()) |
return true; |
- // TODO(mkwst): Look into moving this to 'FrameFetchContext::canRequestInternal' alongside the |
- // 'frame-src' checks. |
+ // If we're loading content into a subframe, check against the parent's Content Security Policy |
+ // and kill the load if that check fails, unless we should bypass the main world's CSP. |
+ if (shouldCheckMainWorldContentSecurityPolicy == CheckContentSecurityPolicy) { |
+ Frame* parentFrame = m_frame->tree().parent(); |
+ if (parentFrame) { |
+ ContentSecurityPolicy* parentPolicy = parentFrame->securityContext()->contentSecurityPolicy(); |
+ if (!parentPolicy->allowChildFrameFromSource(request.url(), request.redirectStatus())) { |
+ // Fire a load event, as timing attacks would otherwise reveal that the |
+ // frame was blocked. This way, it looks like every other cross-origin |
+ // page load. |
+ m_frame->document()->enforceSandboxFlags(SandboxOrigin); |
+ m_frame->owner()->dispatchLoad(); |
+ return false; |
+ } |
+ } |
+ } |
+ |
bool isFormSubmission = type == NavigationTypeFormSubmitted || type == NavigationTypeFormResubmitted; |
if (isFormSubmission && !m_frame->document()->contentSecurityPolicy()->allowFormAction(request.url())) |
return false; |
@@ -1396,7 +1412,7 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty |
frameLoadRequest.resourceRequest().setRequestContext(determineRequestContextFromNavigationType(navigationType)); |
frameLoadRequest.resourceRequest().setFrameType(m_frame->isMainFrame() ? WebURLRequest::FrameTypeTopLevel : WebURLRequest::FrameTypeNested); |
ResourceRequest& request = frameLoadRequest.resourceRequest(); |
- if (!shouldContinueForNavigationPolicy(request, frameLoadRequest.substituteData(), nullptr, navigationType, navigationPolicy, type == FrameLoadTypeReplaceCurrentItem, frameLoadRequest.clientRedirect() == ClientRedirectPolicy::ClientRedirect)) |
+ if (!shouldContinueForNavigationPolicy(request, frameLoadRequest.substituteData(), nullptr, frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy(), navigationType, navigationPolicy, type == FrameLoadTypeReplaceCurrentItem, frameLoadRequest.clientRedirect() == ClientRedirectPolicy::ClientRedirect)) |
return; |
m_frame->document()->cancelParsing(); |
@@ -1432,7 +1448,7 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty |
double triggeringEventTime = frameLoadRequest.triggeringEvent() ? frameLoadRequest.triggeringEvent()->platformTimeStamp() : 0; |
client()->dispatchDidStartProvisionalLoad(triggeringEventTime); |
ASSERT(m_provisionalDocumentLoader); |
- m_provisionalDocumentLoader->startLoadingMainResource(frameLoadRequest.shouldCheckMainWorldContentSecurityPolicy()); |
+ m_provisionalDocumentLoader->startLoadingMainResource(); |
takeObjectSnapshot(); |
} |