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 597cb1b1b0fa65389667095eee27b036cf4d37c7..8ad62d8ea31f6ccaf43e84af30e71be7817b0f26 100644 |
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
@@ -883,6 +883,36 @@ bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) { |
return false; |
} |
+ // Block content-initiated, top-frame navigations to data URLs. Allow if the |
+ // top frame of the initiator is already a data URL so that links, redirects |
+ // et.c. on data URLs aren't broken. |
+ if (m_frame->isMainFrame() && url.protocol() == "data") { |
+ // TODO: Check request()->downloadToFile() |
+ bool canLoadDataURL = true; |
+ if (request.originDocument()->frame()->tree().top()->isLocalFrame()) { |
+ Document* topFrameDocument = |
+ toLocalFrame(request.originDocument()->frame()->tree().top()) |
+ ->document(); |
+ canLoadDataURL = |
+ topFrameDocument->url().protocol() == "data" || |
+ topFrameDocument->getSecurityOrigin()->canNavigateInTopFrame(url); |
+ } else { |
+ RemoteFrame* topFrame = |
+ toRemoteFrame(request.originDocument()->frame()->tree().top()); |
+ // TODO(meacer): We don't know the URL of the remote frame, so this is |
+ // only an estimate. |
+ canLoadDataURL = |
+ topFrame->securityContext()->getSecurityOrigin()->isUnique() || |
+ topFrame->securityContext() |
+ ->getSecurityOrigin() |
+ ->canNavigateInTopFrame(url); |
+ } |
+ if (!canLoadDataURL) { |
+ reportTopLevelNavigationFailed(m_frame, url.elidedString()); |
+ return false; |
+ } |
+ } |
+ |
if (!request.form() && request.frameName().isEmpty()) |
request.setFrameName(m_frame->document()->baseTarget()); |
return true; |
@@ -1124,6 +1154,17 @@ void FrameLoader::reportLocalLoadFailed(LocalFrame* frame, const String& url) { |
"Not allowed to load local resource: " + url)); |
} |
+void FrameLoader::reportTopLevelNavigationFailed(LocalFrame* frame, |
+ const String& url) { |
+ DCHECK(!url.isEmpty()); |
+ if (!frame) |
+ return; |
+ |
+ frame->document()->addConsoleMessage(ConsoleMessage::create( |
+ SecurityMessageSource, ErrorMessageLevel, |
+ "Not allowed to top-level navigate to resource: " + url)); |
+} |
+ |
void FrameLoader::stopAllLoaders() { |
if (m_frame->document()->pageDismissalEventBeingDispatched() != |
Document::NoDismissal) |