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

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

Issue 2877893002: Make UseCounter take a LocaFrame instead of any Frame (Closed)
Patch Set: Fix compile Created 3 years, 7 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
« no previous file with comments | « third_party/WebKit/Source/core/frame/Frame.h ('k') | third_party/WebKit/Source/core/frame/LocalFrame.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 28a96d4a9feb27d840f133551d8a334524fcce92..23fdf4279db7e8df1975adee9c5973b1d692ed2e 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -45,7 +45,6 @@
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "core/probe/CoreProbes.h"
-#include "platform/Histogram.h"
#include "platform/InstanceCounters.h"
#include "platform/UserGestureIndicator.h"
#include "platform/feature_policy/FeaturePolicy.h"
@@ -132,224 +131,13 @@ ChromeClient& Frame::GetChromeClient() const {
}
Frame* Frame::FindFrameForNavigation(const AtomicString& name,
- Frame& active_frame) {
+ LocalFrame& active_frame) {
Frame* frame = Tree().Find(name);
if (!frame || !active_frame.CanNavigate(*frame))
return nullptr;
return frame;
}
-static bool CanAccessAncestor(const SecurityOrigin& active_security_origin,
- const Frame* target_frame) {
- // targetFrame can be 0 when we're trying to navigate a top-level frame
- // that has a 0 opener.
- if (!target_frame)
- return false;
-
- const bool is_local_active_origin = active_security_origin.IsLocal();
- for (const Frame* ancestor_frame = target_frame; ancestor_frame;
- ancestor_frame = ancestor_frame->Tree().Parent()) {
- const SecurityOrigin* ancestor_security_origin =
- ancestor_frame->GetSecurityContext()->GetSecurityOrigin();
- if (active_security_origin.CanAccess(ancestor_security_origin))
- return true;
-
- // Allow file URL descendant navigation even when
- // allowFileAccessFromFileURLs is false.
- // FIXME: It's a bit strange to special-case local origins here. Should we
- // be doing something more general instead?
- if (is_local_active_origin && ancestor_security_origin->IsLocal())
- return true;
- }
-
- return false;
-}
-
-bool Frame::CanNavigate(const Frame& target_frame) {
- String error_reason;
- const bool is_allowed_navigation =
- CanNavigateWithoutFramebusting(target_frame, error_reason);
- const bool sandboxed =
- GetSecurityContext()->GetSandboxFlags() != kSandboxNone;
- const bool has_user_gesture =
- IsLocalFrame() ? ToLocalFrame(this)->HasReceivedUserGesture() : false;
-
- // Top navigation in sandbox with or w/o 'allow-top-navigation'.
- if (target_frame != this && sandboxed && target_frame == Tree().Top()) {
- UseCounter::Count(&target_frame, UseCounter::kTopNavInSandbox);
- if (!has_user_gesture) {
- UseCounter::Count(&target_frame,
- UseCounter::kTopNavInSandboxWithoutGesture);
- }
- }
-
- // Top navigation w/o sandbox or in sandbox with 'allow-top-navigation'.
- if (target_frame != this &&
- !GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
- target_frame == Tree().Top()) {
- DEFINE_STATIC_LOCAL(EnumerationHistogram, framebust_histogram,
- ("WebCore.Framebust", 4));
- const unsigned kUserGestureBit = 0x1;
- const unsigned kAllowedBit = 0x2;
- unsigned framebust_params = 0;
- UseCounter::Count(&target_frame, UseCounter::kTopNavigationFromSubFrame);
-
- if (has_user_gesture)
- framebust_params |= kUserGestureBit;
- if (sandboxed) { // Sandboxed with 'allow-top-navigation'.
- UseCounter::Count(&target_frame, UseCounter::kTopNavInSandboxWithPerm);
- if (!has_user_gesture) {
- UseCounter::Count(&target_frame,
- UseCounter::kTopNavInSandboxWithPermButNoGesture);
- }
- }
-
- if (is_allowed_navigation)
- framebust_params |= kAllowedBit;
- framebust_histogram.Count(framebust_params);
- if (has_user_gesture || is_allowed_navigation)
- return true;
- // Frame-busting used to be generally allowed in most situations, but may
- // now blocked if the document initiating the navigation has never received
- // a user gesture.
- if (!RuntimeEnabledFeatures::
- framebustingNeedsSameOriginOrUserGestureEnabled()) {
- String target_frame_description =
- target_frame.IsLocalFrame() ? "with URL '" +
- ToLocalFrame(target_frame)
- .GetDocument()
- ->Url()
- .GetString() +
- "'"
- : "with origin '" +
- target_frame.GetSecurityContext()
- ->GetSecurityOrigin()
- ->ToString() +
- "'";
- String message = "Frame with URL '" +
- ToLocalFrame(this)->GetDocument()->Url().GetString() +
- "' attempted to navigate its top-level window " +
- target_frame_description +
- ". Navigating the top-level window from a cross-origin "
- "iframe will soon require that the iframe has received "
- "a user gesture. See "
- "https://www.chromestatus.com/features/"
- "5851021045661696.";
- PrintNavigationWarning(message);
- return true;
- }
- error_reason =
- "The frame attempting navigation is targeting its top-level window, "
- "but is neither same-origin with its target nor has it received a "
- "user gesture. See "
- "https://www.chromestatus.com/features/5851021045661696.";
- PrintNavigationErrorMessage(target_frame, error_reason.Latin1().data());
- if (IsLocalFrame()) {
- ToLocalFrame(this)->GetNavigationScheduler().SchedulePageBlock(
- ToLocalFrame(this)->GetDocument(), ResourceError::ACCESS_DENIED);
- }
- return false;
- }
- if (!is_allowed_navigation && !error_reason.IsNull())
- PrintNavigationErrorMessage(target_frame, error_reason.Latin1().data());
- return is_allowed_navigation;
-}
-
-bool Frame::CanNavigateWithoutFramebusting(const Frame& target_frame,
- String& reason) {
- if (&target_frame == this)
- return true;
-
- if (GetSecurityContext()->IsSandboxed(kSandboxNavigation)) {
- if (!target_frame.Tree().IsDescendantOf(this) &&
- !target_frame.IsMainFrame()) {
- reason =
- "The frame attempting navigation is sandboxed, and is therefore "
- "disallowed from navigating its ancestors.";
- return false;
- }
-
- // Sandboxed frames can also navigate popups, if the
- // 'allow-sandbox-escape-via-popup' flag is specified, or if
- // 'allow-popups' flag is specified, or if the
- if (target_frame.IsMainFrame() && target_frame != Tree().Top() &&
- GetSecurityContext()->IsSandboxed(
- kSandboxPropagatesToAuxiliaryBrowsingContexts) &&
- (GetSecurityContext()->IsSandboxed(kSandboxPopups) ||
- target_frame.Client()->Opener() != this)) {
- reason =
- "The frame attempting navigation is sandboxed and is trying "
- "to navigate a popup, but is not the popup's opener and is not "
- "set to propagate sandboxing to popups.";
- return false;
- }
-
- // Top navigation is forbidden unless opted-in. allow-top-navigation or
- // allow-top-navigation-by-user-activation will also skips origin checks.
- if (target_frame == Tree().Top()) {
- if (GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
- GetSecurityContext()->IsSandboxed(
- kSandboxTopNavigationByUserActivation)) {
- reason =
- "The frame attempting navigation of the top-level window is "
- "sandboxed, but the flag of 'allow-top-navigation' or "
- "'allow-top-navigation-by-user-activation' is not set.";
- return false;
- }
- if (GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
- !GetSecurityContext()->IsSandboxed(
- kSandboxTopNavigationByUserActivation) &&
- !UserGestureIndicator::ProcessingUserGesture()) {
- // With only 'allow-top-navigation-by-user-activation' (but not
- // 'allow-top-navigation'), top navigation requires a user gesture.
- reason =
- "The frame attempting navigation of the top-level window is "
- "sandboxed with the 'allow-top-navigation-by-user-activation' "
- "flag, but has no user activation (aka gesture). See "
- "https://www.chromestatus.com/feature/5629582019395584.";
- return false;
- }
- return true;
- }
- }
-
- DCHECK(GetSecurityContext()->GetSecurityOrigin());
- SecurityOrigin& origin = *GetSecurityContext()->GetSecurityOrigin();
-
- // This is the normal case. A document can navigate its decendant frames,
- // or, more generally, a document can navigate a frame if the document is
- // in the same origin as any of that frame's ancestors (in the frame
- // hierarchy).
- //
- // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
- // historical information about this security check.
- if (CanAccessAncestor(origin, &target_frame))
- return true;
-
- // Top-level frames are easier to navigate than other frames because they
- // display their URLs in the address bar (in most browsers). However, there
- // are still some restrictions on navigation to avoid nuisance attacks.
- // Specifically, a document can navigate a top-level frame if that frame
- // opened the document or if the document is the same-origin with any of
- // the top-level frame's opener's ancestors (in the frame hierarchy).
- //
- // In both of these cases, the document performing the navigation is in
- // some way related to the frame being navigate (e.g., by the "opener"
- // and/or "parent" relation). Requiring some sort of relation prevents a
- // document from navigating arbitrary, unrelated top-level frames.
- if (!target_frame.Tree().Parent()) {
- if (target_frame == Client()->Opener())
- return true;
- if (CanAccessAncestor(origin, target_frame.Client()->Opener()))
- return true;
- }
-
- reason =
- "The frame attempting navigation is neither same-origin with the target, "
- "nor is it the target's parent or opener.";
- return false;
-}
-
Frame* Frame::FindUnsafeParentScrollPropagationBoundary() {
Frame* current_frame = this;
Frame* ancestor_frame = Tree().Parent();
« no previous file with comments | « third_party/WebKit/Source/core/frame/Frame.h ('k') | third_party/WebKit/Source/core/frame/LocalFrame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698