Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(932)

Unified Diff: third_party/WebKit/Source/core/frame/Frame.cpp

Issue 2092293002: Block framebusts without a user gesture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: better flag description Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/frame/Frame.cpp
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp
index 6fc666a026896c7f746b408538fa0e0ff8d525cd..16a6b5cd051f9eff96e9ca5158dba9aef41566a5 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -42,6 +42,7 @@
#include "core/layout/LayoutPart.h"
#include "core/loader/EmptyClients.h"
#include "core/loader/FrameLoaderClient.h"
+#include "core/loader/NavigationScheduler.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "platform/Histogram.h"
@@ -168,19 +169,28 @@ bool Frame::canNavigate(const Frame& targetFrame)
String errorReason;
bool isAllowedNavigation = canNavigateWithoutFramebusting(targetFrame, errorReason);
- // Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
if (targetFrame != this && !securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top()) {
DEFINE_STATIC_LOCAL(EnumerationHistogram, framebustHistogram, ("WebCore.Framebust", 4));
const unsigned userGestureBit = 0x1;
const unsigned allowedBit = 0x2;
unsigned framebustParams = 0;
UseCounter::count(&targetFrame, UseCounter::TopNavigationFromSubFrame);
- if (UserGestureIndicator::processingUserGesture())
+ bool hasUserGesture = UserGestureIndicator::processingUserGesture();
+ if (hasUserGesture)
framebustParams |= userGestureBit;
if (isAllowedNavigation)
framebustParams |= allowedBit;
framebustHistogram.count(framebustParams);
- return true;
+ // Frame-busting used to be generally allowed in most situations, but may now blocked if there is no user gesture.
+ if (!RuntimeEnabledFeatures::framebustingNeedsSameOriginOrUserGestureEnabled())
+ return true;
+ if (hasUserGesture || isAllowedNavigation)
+ return true;
+ errorReason = "The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor is it processing a user gesture. See https://www.chromestatus.com/features/5851021045661696.";
+ printNavigationErrorMessage(targetFrame, errorReason.latin1().data());
+ if (isLocalFrame())
+ toLocalFrame(this)->navigationScheduler().schedulePageBlock(toLocalFrame(this)->document());
+ return false;
}
if (!isAllowedNavigation && !errorReason.isNull())
printNavigationErrorMessage(targetFrame, errorReason.latin1().data());
@@ -198,6 +208,10 @@ bool Frame::canNavigateWithoutFramebusting(const Frame& targetFrame, String& rea
if (targetFrame == targetFrame.tree().top() && targetFrame.tree().top() != tree().top() && !securityContext()->isSandboxed(SandboxPropagatesToAuxiliaryBrowsingContexts))
return true;
+ // Top navigation can be opted-in.
+ if (!securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top())
+ return true;
+
// Otherwise, block the navigation.
if (securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top())
reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";

Powered by Google App Engine
This is Rietveld 408576698