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

Side by Side Diff: third_party/WebKit/Source/core/frame/LocalFrame.cpp

Issue 2877893002: Make UseCounter take a LocaFrame instead of any Frame (Closed)
Patch Set: Fix compile Created 3 years, 6 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Simon Hausmann <hausmann@kde.org> 5 * 2000 Simon Hausmann <hausmann@kde.org>
6 * 2000 Stefan Schimanski <1Stein@gmx.de> 6 * 2000 Stefan Schimanski <1Stein@gmx.de>
7 * 2001 George Staikos <staikos@kde.org> 7 * 2001 George Staikos <staikos@kde.org>
8 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All 8 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All
9 * rights reserved. 9 * rights reserved.
10 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com> 10 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #include "core/paint/ObjectPainter.h" 73 #include "core/paint/ObjectPainter.h"
74 #include "core/paint/PaintInfo.h" 74 #include "core/paint/PaintInfo.h"
75 #include "core/paint/PaintLayer.h" 75 #include "core/paint/PaintLayer.h"
76 #include "core/paint/PaintLayerPainter.h" 76 #include "core/paint/PaintLayerPainter.h"
77 #include "core/paint/TransformRecorder.h" 77 #include "core/paint/TransformRecorder.h"
78 #include "core/plugins/PluginView.h" 78 #include "core/plugins/PluginView.h"
79 #include "core/probe/CoreProbes.h" 79 #include "core/probe/CoreProbes.h"
80 #include "core/svg/SVGDocumentExtensions.h" 80 #include "core/svg/SVGDocumentExtensions.h"
81 #include "core/timing/Performance.h" 81 #include "core/timing/Performance.h"
82 #include "platform/DragImage.h" 82 #include "platform/DragImage.h"
83 #include "platform/Histogram.h"
83 #include "platform/PluginScriptForbiddenScope.h" 84 #include "platform/PluginScriptForbiddenScope.h"
84 #include "platform/RuntimeEnabledFeatures.h" 85 #include "platform/RuntimeEnabledFeatures.h"
85 #include "platform/ScriptForbiddenScope.h" 86 #include "platform/ScriptForbiddenScope.h"
86 #include "platform/WebFrameScheduler.h" 87 #include "platform/WebFrameScheduler.h"
87 #include "platform/graphics/GraphicsContext.h" 88 #include "platform/graphics/GraphicsContext.h"
88 #include "platform/graphics/StaticBitmapImage.h" 89 #include "platform/graphics/StaticBitmapImage.h"
89 #include "platform/graphics/paint/ClipRecorder.h" 90 #include "platform/graphics/paint/ClipRecorder.h"
90 #include "platform/graphics/paint/PaintCanvas.h" 91 #include "platform/graphics/paint/PaintCanvas.h"
91 #include "platform/graphics/paint/PaintController.h" 92 #include "platform/graphics/paint/PaintController.h"
92 #include "platform/graphics/paint/PaintRecordBuilder.h" 93 #include "platform/graphics/paint/PaintRecordBuilder.h"
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 WebFrameScheduler* LocalFrame::FrameScheduler() { 913 WebFrameScheduler* LocalFrame::FrameScheduler() {
913 return frame_scheduler_.get(); 914 return frame_scheduler_.get();
914 } 915 }
915 916
916 void LocalFrame::ScheduleVisualUpdateUnlessThrottled() { 917 void LocalFrame::ScheduleVisualUpdateUnlessThrottled() {
917 if (ShouldThrottleRendering()) 918 if (ShouldThrottleRendering())
918 return; 919 return;
919 GetPage()->Animator().ScheduleVisualUpdate(this); 920 GetPage()->Animator().ScheduleVisualUpdate(this);
920 } 921 }
921 922
923 bool LocalFrame::CanNavigate(const Frame& target_frame) {
924 String error_reason;
925 const bool is_allowed_navigation =
926 CanNavigateWithoutFramebusting(target_frame, error_reason);
927 const bool sandboxed =
928 GetSecurityContext()->GetSandboxFlags() != kSandboxNone;
929 const bool has_user_gesture = HasReceivedUserGesture();
930
931 // Top navigation in sandbox with or w/o 'allow-top-navigation'.
932 if (target_frame != this && sandboxed && target_frame == Tree().Top()) {
933 UseCounter::Count(this, UseCounter::kTopNavInSandbox);
934 if (!has_user_gesture) {
935 UseCounter::Count(this, UseCounter::kTopNavInSandboxWithoutGesture);
936 }
937 }
938
939 // Top navigation w/o sandbox or in sandbox with 'allow-top-navigation'.
940 if (target_frame != this &&
941 !GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
942 target_frame == Tree().Top()) {
943 DEFINE_STATIC_LOCAL(EnumerationHistogram, framebust_histogram,
944 ("WebCore.Framebust", 4));
945 const unsigned kUserGestureBit = 0x1;
946 const unsigned kAllowedBit = 0x2;
947 unsigned framebust_params = 0;
948
949 if (has_user_gesture)
950 framebust_params |= kUserGestureBit;
951
952 UseCounter::Count(this, UseCounter::kTopNavigationFromSubFrame);
953 if (sandboxed) { // Sandboxed with 'allow-top-navigation'.
954 UseCounter::Count(this, UseCounter::kTopNavInSandboxWithPerm);
955 if (!has_user_gesture) {
956 UseCounter::Count(this,
957 UseCounter::kTopNavInSandboxWithPermButNoGesture);
958 }
959 }
960
961 if (is_allowed_navigation)
962 framebust_params |= kAllowedBit;
963 framebust_histogram.Count(framebust_params);
964 if (has_user_gesture || is_allowed_navigation)
965 return true;
966 // Frame-busting used to be generally allowed in most situations, but may
967 // now blocked if the document initiating the navigation has never received
968 // a user gesture.
969 if (!RuntimeEnabledFeatures::
970 framebustingNeedsSameOriginOrUserGestureEnabled()) {
971 String target_frame_description =
972 target_frame.IsLocalFrame() ? "with URL '" +
973 ToLocalFrame(target_frame)
974 .GetDocument()
975 ->Url()
976 .GetString() +
977 "'"
978 : "with origin '" +
979 target_frame.GetSecurityContext()
980 ->GetSecurityOrigin()
981 ->ToString() +
982 "'";
983 String message = "Frame with URL '" + GetDocument()->Url().GetString() +
984 "' attempted to navigate its top-level window " +
985 target_frame_description +
986 ". Navigating the top-level window from a cross-origin "
987 "iframe will soon require that the iframe has received "
988 "a user gesture. See "
989 "https://www.chromestatus.com/features/"
990 "5851021045661696.";
991 PrintNavigationWarning(message);
992 return true;
993 }
994 error_reason =
995 "The frame attempting navigation is targeting its top-level window, "
996 "but is neither same-origin with its target nor has it received a "
997 "user gesture. See "
998 "https://www.chromestatus.com/features/5851021045661696.";
999 PrintNavigationErrorMessage(target_frame, error_reason.Latin1().data());
1000 GetNavigationScheduler().SchedulePageBlock(GetDocument(),
1001 ResourceError::ACCESS_DENIED);
1002 return false;
1003 }
1004 if (!is_allowed_navigation && !error_reason.IsNull())
1005 PrintNavigationErrorMessage(target_frame, error_reason.Latin1().data());
1006 return is_allowed_navigation;
1007 }
1008
1009 static bool CanAccessAncestor(const SecurityOrigin& active_security_origin,
1010 const Frame* target_frame) {
1011 // targetFrame can be 0 when we're trying to navigate a top-level frame
1012 // that has a 0 opener.
1013 if (!target_frame)
1014 return false;
1015
1016 const bool is_local_active_origin = active_security_origin.IsLocal();
1017 for (const Frame* ancestor_frame = target_frame; ancestor_frame;
1018 ancestor_frame = ancestor_frame->Tree().Parent()) {
1019 const SecurityOrigin* ancestor_security_origin =
1020 ancestor_frame->GetSecurityContext()->GetSecurityOrigin();
1021 if (active_security_origin.CanAccess(ancestor_security_origin))
1022 return true;
1023
1024 // Allow file URL descendant navigation even when
1025 // allowFileAccessFromFileURLs is false.
1026 // FIXME: It's a bit strange to special-case local origins here. Should we
1027 // be doing something more general instead?
1028 if (is_local_active_origin && ancestor_security_origin->IsLocal())
1029 return true;
1030 }
1031
1032 return false;
1033 }
1034
1035 bool LocalFrame::CanNavigateWithoutFramebusting(const Frame& target_frame,
1036 String& reason) {
1037 if (&target_frame == this)
1038 return true;
1039
1040 if (GetSecurityContext()->IsSandboxed(kSandboxNavigation)) {
1041 if (!target_frame.Tree().IsDescendantOf(this) &&
1042 !target_frame.IsMainFrame()) {
1043 reason =
1044 "The frame attempting navigation is sandboxed, and is therefore "
1045 "disallowed from navigating its ancestors.";
1046 return false;
1047 }
1048
1049 // Sandboxed frames can also navigate popups, if the
1050 // 'allow-sandbox-escape-via-popup' flag is specified, or if
1051 // 'allow-popups' flag is specified, or if the
1052 if (target_frame.IsMainFrame() && target_frame != Tree().Top() &&
1053 GetSecurityContext()->IsSandboxed(
1054 kSandboxPropagatesToAuxiliaryBrowsingContexts) &&
1055 (GetSecurityContext()->IsSandboxed(kSandboxPopups) ||
1056 target_frame.Client()->Opener() != this)) {
1057 reason =
1058 "The frame attempting navigation is sandboxed and is trying "
1059 "to navigate a popup, but is not the popup's opener and is not "
1060 "set to propagate sandboxing to popups.";
1061 return false;
1062 }
1063
1064 // Top navigation is forbidden unless opted-in. allow-top-navigation or
1065 // allow-top-navigation-by-user-activation will also skips origin checks.
1066 if (target_frame == Tree().Top()) {
1067 if (GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
1068 GetSecurityContext()->IsSandboxed(
1069 kSandboxTopNavigationByUserActivation)) {
1070 reason =
1071 "The frame attempting navigation of the top-level window is "
1072 "sandboxed, but the flag of 'allow-top-navigation' or "
1073 "'allow-top-navigation-by-user-activation' is not set.";
1074 return false;
1075 }
1076 if (GetSecurityContext()->IsSandboxed(kSandboxTopNavigation) &&
1077 !GetSecurityContext()->IsSandboxed(
1078 kSandboxTopNavigationByUserActivation) &&
1079 !UserGestureIndicator::ProcessingUserGesture()) {
1080 // With only 'allow-top-navigation-by-user-activation' (but not
1081 // 'allow-top-navigation'), top navigation requires a user gesture.
1082 reason =
1083 "The frame attempting navigation of the top-level window is "
1084 "sandboxed with the 'allow-top-navigation-by-user-activation' "
1085 "flag, but has no user activation (aka gesture). See "
1086 "https://www.chromestatus.com/feature/5629582019395584.";
1087 return false;
1088 }
1089 return true;
1090 }
1091 }
1092
1093 DCHECK(GetSecurityContext()->GetSecurityOrigin());
1094 SecurityOrigin& origin = *GetSecurityContext()->GetSecurityOrigin();
1095
1096 // This is the normal case. A document can navigate its decendant frames,
1097 // or, more generally, a document can navigate a frame if the document is
1098 // in the same origin as any of that frame's ancestors (in the frame
1099 // hierarchy).
1100 //
1101 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
1102 // historical information about this security check.
1103 if (CanAccessAncestor(origin, &target_frame))
1104 return true;
1105
1106 // Top-level frames are easier to navigate than other frames because they
1107 // display their URLs in the address bar (in most browsers). However, there
1108 // are still some restrictions on navigation to avoid nuisance attacks.
1109 // Specifically, a document can navigate a top-level frame if that frame
1110 // opened the document or if the document is the same-origin with any of
1111 // the top-level frame's opener's ancestors (in the frame hierarchy).
1112 //
1113 // In both of these cases, the document performing the navigation is in
1114 // some way related to the frame being navigate (e.g., by the "opener"
1115 // and/or "parent" relation). Requiring some sort of relation prevents a
1116 // document from navigating arbitrary, unrelated top-level frames.
1117 if (!target_frame.Tree().Parent()) {
1118 if (target_frame == Client()->Opener())
1119 return true;
1120 if (CanAccessAncestor(origin, target_frame.Client()->Opener()))
1121 return true;
1122 }
1123
1124 reason =
1125 "The frame attempting navigation is neither same-origin with the target, "
1126 "nor is it the target's parent or opener.";
1127 return false;
1128 }
1129
922 LocalFrameClient* LocalFrame::Client() const { 1130 LocalFrameClient* LocalFrame::Client() const {
923 return static_cast<LocalFrameClient*>(Frame::Client()); 1131 return static_cast<LocalFrameClient*>(Frame::Client());
924 } 1132 }
925 1133
926 ContentSettingsClient* LocalFrame::GetContentSettingsClient() { 1134 ContentSettingsClient* LocalFrame::GetContentSettingsClient() {
927 return Client() ? &Client()->GetContentSettingsClient() : nullptr; 1135 return Client() ? &Client()->GetContentSettingsClient() : nullptr;
928 } 1136 }
929 1137
930 PluginData* LocalFrame::GetPluginData() const { 1138 PluginData* LocalFrame::GetPluginData() const {
931 if (!Loader().AllowPlugins(kNotAboutToInstantiatePlugin)) 1139 if (!Loader().AllowPlugins(kNotAboutToInstantiatePlugin))
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 node = GetDocument()->FocusedElement(); 1195 node = GetDocument()->FocusedElement();
988 } 1196 }
989 1197
990 if (node) { 1198 if (node) {
991 return node->GetWebPluginContainerBase(); 1199 return node->GetWebPluginContainerBase();
992 } 1200 }
993 return nullptr; 1201 return nullptr;
994 } 1202 }
995 1203
996 } // namespace blink 1204 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/LocalFrame.h ('k') | third_party/WebKit/Source/core/frame/UseCounter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698