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

Side by Side Diff: extensions/browser/guest_view/web_view/web_view_guest.cc

Issue 890183002: Allow Signin page to open other chrome:// URLs if login content in <webview> (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/guest_view/web_view/web_view_guest.h" 5 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "content/public/browser/browser_context.h" 10 #include "content/public/browser/browser_context.h"
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 return &javascript_dialog_helper_; 868 return &javascript_dialog_helper_;
869 } 869 }
870 870
871 void WebViewGuest::NavigateGuest(const std::string& src, 871 void WebViewGuest::NavigateGuest(const std::string& src,
872 bool force_navigation) { 872 bool force_navigation) {
873 if (src.empty()) 873 if (src.empty())
874 return; 874 return;
875 875
876 GURL url = ResolveURL(src); 876 GURL url = ResolveURL(src);
877 877
878 // Do not allow navigating a guest to schemes other than known safe schemes. 878 LoadURLWithParams(url, content::Referrer(),
879 // This will block the embedder trying to load unwanted schemes, e.g.
880 // chrome://settings.
881 bool scheme_is_blocked =
882 (!content::ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
883 url.scheme()) &&
884 !url.SchemeIs(url::kAboutScheme)) ||
885 url.SchemeIs(url::kJavaScriptScheme);
886 if (scheme_is_blocked || !url.is_valid()) {
887 LoadAbort(true /* is_top_level */, url,
888 net::ErrorToShortString(net::ERR_ABORTED));
889 NavigateGuest(url::kAboutBlankURL, true /* force_navigation */);
890 return;
891 }
892 if (!force_navigation && (src_ == url))
893 return;
894
895 GURL validated_url(url);
896 web_contents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
897 // As guests do not swap processes on navigation, only navigations to
898 // normal web URLs are supported. No protocol handlers are installed for
899 // other schemes (e.g., WebUI or extensions), and no permissions or bindings
900 // can be granted to the guest process.
901 LoadURLWithParams(validated_url,
902 content::Referrer(),
903 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, 879 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
904 web_contents()); 880 force_navigation);
905
906 src_ = validated_url;
907 } 881 }
908 882
909 bool WebViewGuest::HandleKeyboardShortcuts( 883 bool WebViewGuest::HandleKeyboardShortcuts(
910 const content::NativeWebKeyboardEvent& event) { 884 const content::NativeWebKeyboardEvent& event) {
911 // <webview> outside of Chrome Apps do not handle keyboard shortcuts. 885 // <webview> outside of Chrome Apps do not handle keyboard shortcuts.
912 if (!in_extension()) 886 if (!in_extension())
913 return false; 887 return false;
914 888
915 if (event.type != blink::WebInputEvent::RawKeyDown) 889 if (event.type != blink::WebInputEvent::RawKeyDown)
916 return false; 890 return false;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 *was_blocked = false; 1085 *was_blocked = false;
1112 RequestNewWindowPermission(disposition, 1086 RequestNewWindowPermission(disposition,
1113 initial_rect, 1087 initial_rect,
1114 user_gesture, 1088 user_gesture,
1115 new_contents); 1089 new_contents);
1116 } 1090 }
1117 1091
1118 content::WebContents* WebViewGuest::OpenURLFromTab( 1092 content::WebContents* WebViewGuest::OpenURLFromTab(
1119 content::WebContents* source, 1093 content::WebContents* source,
1120 const content::OpenURLParams& params) { 1094 const content::OpenURLParams& params) {
1095 // There are two use cases to consider from a security perspective:
1096 // 1.) Renderer-initiated navigation to chrome:// must always be blocked even
1097 // if the <webview> is in WebUI. This is handled by
1098 // WebViewGuest::LoadURLWithParams. WebViewGuest::NavigateGuest will also
1099 // call LoadURLWithParams. CreateNewGuestWebViewWindow creates a new
1100 // WebViewGuest which will call NavigateGuest in DidInitialize.
1101 // 2.) The Language Settings context menu item should always work, both in
1102 // Chrome Apps and WebUI. This is a browser initiated request and so
1103 // we pass it along to the embedder's WebContentsDelegate to get the
1104 // browser to perform the action for the <webview>.
1105 if (!params.is_renderer_initiated) {
1106 if (!owner_web_contents()->GetDelegate())
1107 return nullptr;
1108 return owner_web_contents()->GetDelegate()->OpenURLFromTab(
1109 owner_web_contents(), params);
1110 }
1111
1121 // If the guest wishes to navigate away prior to attachment then we save the 1112 // If the guest wishes to navigate away prior to attachment then we save the
1122 // navigation to perform upon attachment. Navigation initializes a lot of 1113 // navigation to perform upon attachment. Navigation initializes a lot of
1123 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest. 1114 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
1124 // Navigation also resumes resource loading which we don't want to allow 1115 // Navigation also resumes resource loading which we don't want to allow
1125 // until attachment. 1116 // until attachment.
1126 if (!attached()) { 1117 if (!attached()) {
1127 WebViewGuest* opener = GetOpener(); 1118 WebViewGuest* opener = GetOpener();
1128 auto it = opener->pending_new_windows_.find(this); 1119 auto it = opener->pending_new_windows_.find(this);
1129 if (it == opener->pending_new_windows_.end()) 1120 if (it == opener->pending_new_windows_.end())
1130 return nullptr; 1121 return nullptr;
1131 const NewWindowInfo& info = it->second; 1122 const NewWindowInfo& info = it->second;
1132 NewWindowInfo new_window_info(params.url, info.name); 1123 NewWindowInfo new_window_info(params.url, info.name);
1133 new_window_info.changed = new_window_info.url != info.url; 1124 new_window_info.changed = new_window_info.url != info.url;
1134 it->second = new_window_info; 1125 it->second = new_window_info;
1135 return nullptr; 1126 return nullptr;
1136 } 1127 }
1128
1129 // This code path is taken if RenderFrameImpl::DecidePolicyForNavigation
1130 // decides that a fork should happen. At the time of writing this comment,
1131 // the only way a well behaving guest could hit this code path is if it
1132 // navigates to a URL that's associated with the default search engine.
1133 // This list of URLs is generated by chrome::GetSearchURLs. Validity checks
1134 // are performed inside LoadURLWithParams such that if the guest attempts
1135 // to navigate to a URL that it is not allowed to navigate to, a 'loadabort'
1136 // event will fire in the embedder, and the guest will be navigated to
1137 // about:blank.
1137 if (params.disposition == CURRENT_TAB) { 1138 if (params.disposition == CURRENT_TAB) {
1138 // This can happen for cross-site redirects. 1139 LoadURLWithParams(params.url, params.referrer, params.transition,
1139 LoadURLWithParams(params.url, params.referrer, params.transition, source); 1140 true /* force_navigation */);
1140 return source; 1141 return web_contents();
1141 } 1142 }
1142 1143
1144 // This code path is taken if Ctrl+Click, middle click or any of the
1145 // keyboard/mouse combinations are used to open a link in a new tab/window.
1146 // This code path is also taken on client-side redirects from about:blank.
1143 CreateNewGuestWebViewWindow(params); 1147 CreateNewGuestWebViewWindow(params);
1144 return nullptr; 1148 return nullptr;
1145 } 1149 }
1146 1150
1147 void WebViewGuest::WebContentsCreated(WebContents* source_contents, 1151 void WebViewGuest::WebContentsCreated(WebContents* source_contents,
1148 int opener_render_frame_id, 1152 int opener_render_frame_id,
1149 const base::string16& frame_name, 1153 const base::string16& frame_name,
1150 const GURL& target_url, 1154 const GURL& target_url,
1151 content::WebContents* new_contents) { 1155 content::WebContents* new_contents) {
1152 auto guest = WebViewGuest::FromWebContents(new_contents); 1156 auto guest = WebViewGuest::FromWebContents(new_contents);
1153 CHECK(guest); 1157 CHECK(guest);
1154 guest->SetOpener(this); 1158 guest->SetOpener(this);
1155 std::string guest_name = base::UTF16ToUTF8(frame_name); 1159 std::string guest_name = base::UTF16ToUTF8(frame_name);
1156 guest->name_ = guest_name; 1160 guest->name_ = guest_name;
1157 pending_new_windows_.insert( 1161 pending_new_windows_.insert(
1158 std::make_pair(guest, NewWindowInfo(target_url, guest_name))); 1162 std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
1159 } 1163 }
1160 1164
1161 void WebViewGuest::LoadURLWithParams(const GURL& url, 1165 void WebViewGuest::LoadURLWithParams(const GURL& url,
1162 const content::Referrer& referrer, 1166 const content::Referrer& referrer,
1163 ui::PageTransition transition_type, 1167 ui::PageTransition transition_type,
1164 content::WebContents* web_contents) { 1168 bool force_navigation) {
1165 content::NavigationController::LoadURLParams load_url_params(url); 1169 // Do not allow navigating a guest to schemes other than known safe schemes.
1170 // This will block the embedder trying to load unwanted schemes, e.g.
1171 // chrome://settings.
Charlie Reis 2015/02/19 22:56:28 nit: chrome:// (settings isn't part of the scheme)
Fady Samuel 2015/02/20 00:33:06 Done.
1172 bool scheme_is_blocked =
1173 (!content::ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
1174 url.scheme()) &&
1175 !url.SchemeIs(url::kAboutScheme)) ||
1176 url.SchemeIs(url::kJavaScriptScheme);
1177 if (scheme_is_blocked || !url.is_valid()) {
1178 LoadAbort(true /* is_top_level */, url,
1179 net::ErrorToShortString(net::ERR_ABORTED));
1180 NavigateGuest(url::kAboutBlankURL, true /* force_navigation */);
1181 return;
1182 }
1183
1184 if (!force_navigation && (src_ == url))
1185 return;
1186
1187 GURL validated_url(url);
1188 web_contents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
1189 // As guests do not swap processes on navigation, only navigations to
1190 // normal web URLs are supported. No protocol handlers are installed for
1191 // other schemes (e.g., WebUI or extensions), and no permissions or bindings
1192 // can be granted to the guest process.
1193 content::NavigationController::LoadURLParams load_url_params(validated_url);
1166 load_url_params.referrer = referrer; 1194 load_url_params.referrer = referrer;
1167 load_url_params.transition_type = transition_type; 1195 load_url_params.transition_type = transition_type;
1168 load_url_params.extra_headers = std::string(); 1196 load_url_params.extra_headers = std::string();
1169 if (is_overriding_user_agent_) { 1197 if (is_overriding_user_agent_) {
1170 load_url_params.override_user_agent = 1198 load_url_params.override_user_agent =
1171 content::NavigationController::UA_OVERRIDE_TRUE; 1199 content::NavigationController::UA_OVERRIDE_TRUE;
1172 } 1200 }
1173 web_contents->GetController().LoadURLWithParams(load_url_params); 1201 web_contents()->GetController().LoadURLWithParams(load_url_params);
1202
1203 src_ = validated_url;
1174 } 1204 }
1175 1205
1176 void WebViewGuest::RequestNewWindowPermission( 1206 void WebViewGuest::RequestNewWindowPermission(
1177 WindowOpenDisposition disposition, 1207 WindowOpenDisposition disposition,
1178 const gfx::Rect& initial_bounds, 1208 const gfx::Rect& initial_bounds,
1179 bool user_gesture, 1209 bool user_gesture,
1180 content::WebContents* new_contents) { 1210 content::WebContents* new_contents) {
1181 auto guest = WebViewGuest::FromWebContents(new_contents); 1211 auto guest = WebViewGuest::FromWebContents(new_contents);
1182 if (!guest) 1212 if (!guest)
1183 return; 1213 return;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(), 1262 WebViewGuest::From(owner_web_contents()->GetRenderProcessHost()->GetID(),
1233 new_window_instance_id); 1263 new_window_instance_id);
1234 if (!guest) 1264 if (!guest)
1235 return; 1265 return;
1236 1266
1237 if (!allow) 1267 if (!allow)
1238 guest->Destroy(); 1268 guest->Destroy();
1239 } 1269 }
1240 1270
1241 } // namespace extensions 1271 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698