15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_request/web_request_permissions.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/resource_request_info.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/info_map.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ResourceRequestInfo; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the URL is sensitive and requests to this URL must not be 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modified/canceled by extensions, e.g. because it is targeted to the webstore 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to check for updates, extension blacklisting, etc. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSensitiveURL(const GURL& url) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(battre) Merge this, CanExtensionAccessURL and 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // PermissionsData::CanAccessPage into one function. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool sensitive_chrome_url = false; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string host = url.host(); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kGoogleCom[] = ".google.com"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kClient[] = "clients"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (EndsWith(host, kGoogleCom, true)) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for "clients[0-9]*.google.com" hosts. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This protects requests to several internal services such as sync, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension update pings, captive portal detection, fraudulent certificate 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reporting, autofill and others. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (StartsWithASCII(host, kClient, true)) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool match = true; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::string::const_iterator i = host.begin() + strlen(kClient), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = host.end() - strlen(kGoogleCom); i != end; ++i) { 422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!isdigit(*i)) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match = false; 442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch break; 452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sensitive_chrome_url = sensitive_chrome_url || match; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This protects requests to safe browsing, link doctor, and possibly 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // others. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sensitive_chrome_url = sensitive_chrome_url || 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndsWith(url.host(), ".clients.google.com", true) || 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) url.host() == "sb-ssl.google.com" || 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (url.host() == "chrome.google.com" && 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartsWithASCII(url.path(), "/webstore", true)); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL::Replacements replacements; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearQuery(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) replacements.ClearRef(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url_without_query = url.ReplaceComponents(replacements); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sensitive_chrome_url || 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_urls::IsWebstoreUpdateUrl(url_without_query) || 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_urls::IsBlacklistUpdateUrl(url); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the scheme is one we want to allow extensions to have access 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to. Extensions still need specific permissions for a given URL, which is 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// covered by CanExtensionAccessURL. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasWebRequestScheme(const GURL& url) { 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return (url.SchemeIs(url::kAboutScheme) || url.SchemeIs(url::kFileScheme) || 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url.SchemeIs(url::kFileSystemScheme) || 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url.SchemeIs(url::kFtpScheme) || url.SchemeIs(url::kHttpScheme) || 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url.SchemeIs(url::kHttpsScheme) || 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.SchemeIs(extensions::kExtensionScheme)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebRequestPermissions::HideRequest( 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const extensions::InfoMap* extension_info_map, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLRequest* request) { 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Hide requests from the Chrome WebStore App or signin process. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (info) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id = info->GetChildID(); 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Never hide requests from guest processes. 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (extensions::WebViewRendererState::GetInstance()->IsGuest(process_id)) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension_info_map && ( 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extension_info_map->IsSigninProcess(process_id) || 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension_info_map->process_map().Contains( 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::kWebStoreAppId, process_id))) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url = request->url(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsSensitiveURL(url) || !HasWebRequestScheme(url); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebRequestPermissions::CanExtensionAccessURL( 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const extensions::InfoMap* extension_info_map, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool crosses_incognito, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HostPermissionsCheck host_permissions_check) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension_info_map can be NULL in testing. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_info_map) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension = 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_info_map->extensions().GetByID(extension_id); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if this event crosses incognito boundaries when it shouldn't. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (crosses_incognito && !extension_info_map->CanCrossIncognito(extension)) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (host_permissions_check) { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case DO_NOT_CHECK_HOST: 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case REQUIRE_HOST_PERMISSION: 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // about: URLs are not covered in host permissions, but are allowed 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // anyway. 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!((url.SchemeIs(url::kAboutScheme) || 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasHostPermission(url) || 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) url.GetOrigin() == extension->url()))) { 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case REQUIRE_ALL_URLS: 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!extension->permissions_data()->HasEffectiveAccessToAllHosts()) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 143