11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright (c) 2012 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_permissions.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_util.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/resource_request_info.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/info_map.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/constants.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/permissions/permissions_data.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/url_request.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "url/gurl.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::ResourceRequestInfo; 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns true if the URL is sensitive and requests to this URL must not be 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// modified/canceled by extensions, e.g. because it is targeted to the webstore 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// to check for updates, extension blacklisting, etc. 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool IsSensitiveURL(const GURL& url) { 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(battre) Merge this, CanExtensionAccessURL and 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // PermissionsData::CanAccessPage into one function. 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool sensitive_chrome_url = false; 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string host = url.host(); 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const char kGoogleCom[] = ".google.com"; 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const char kClient[] = "clients"; 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (EndsWith(host, kGoogleCom, true)) { 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check for "clients[0-9]*.google.com" hosts. 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This protects requests to several internal services such as sync, 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // extension update pings, captive portal detection, fraudulent certificate 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // reporting, autofill and others. 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (StartsWithASCII(host, kClient, true)) { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool match = true; 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::string::const_iterator i = host.begin() + strlen(kClient), 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci end = host.end() - strlen(kGoogleCom); i != end; ++i) { 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!isdigit(*i)) { 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci match = false; 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sensitive_chrome_url = sensitive_chrome_url || match; 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This protects requests to safe browsing, link doctor, and possibly 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // others. 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sensitive_chrome_url = sensitive_chrome_url || 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EndsWith(url.host(), ".clients.google.com", true) || 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.host() == "sb-ssl.google.com" || 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (url.host() == "chrome.google.com" && 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StartsWithASCII(url.path(), "/webstore", true)); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL::Replacements replacements; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci replacements.ClearQuery(); 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci replacements.ClearRef(); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url_without_query = url.ReplaceComponents(replacements); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return sensitive_chrome_url || 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_urls::IsWebstoreUpdateUrl(url_without_query) || 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_urls::IsBlacklistUpdateUrl(url); 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns true if the scheme is one we want to allow extensions to have access 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// to. Extensions still need specific permissions for a given URL, which is 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// covered by CanExtensionAccessURL. 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool HasWebRequestScheme(const GURL& url) { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (url.SchemeIs(url::kAboutScheme) || url.SchemeIs(url::kFileScheme) || 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.SchemeIs(url::kFileSystemScheme) || 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.SchemeIs(url::kFtpScheme) || url.SchemeIs(url::kHttpScheme) || 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.SchemeIs(url::kHttpsScheme) || 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.SchemeIs(extensions::kExtensionScheme)); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WebRequestPermissions::HideRequest( 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const extensions::InfoMap* extension_info_map, 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::URLRequest* request) { 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Hide requests from the Chrome WebStore App or signin process. 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (info) { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int process_id = info->GetChildID(); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Never hide requests from guest processes. 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (extensions::WebViewRendererState::GetInstance()->IsGuest(process_id)) 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (extension_info_map && ( 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_info_map->IsSigninProcess(process_id) || 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_info_map->process_map().Contains( 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::kWebStoreAppId, process_id))) { 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& url = request->url(); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return IsSensitiveURL(url) || !HasWebRequestScheme(url); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool WebRequestPermissions::CanExtensionAccessURL( 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const extensions::InfoMap* extension_info_map, 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& extension_id, 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& url, 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool crosses_incognito, 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HostPermissionsCheck host_permissions_check) { 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // extension_info_map can be NULL in testing. 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extension_info_map) 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const extensions::Extension* extension = 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_info_map->extensions().GetByID(extension_id); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extension) 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check if this event crosses incognito boundaries when it shouldn't. 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (crosses_incognito && !extension_info_map->CanCrossIncognito(extension)) 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (host_permissions_check) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case DO_NOT_CHECK_HOST: 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case REQUIRE_HOST_PERMISSION: 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // about: URLs are not covered in host permissions, but are allowed 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // anyway. 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!((url.SchemeIs(url::kAboutScheme) || 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension->permissions_data()->HasHostPermission(url) || 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url.GetOrigin() == extension->url()))) { 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case REQUIRE_ALL_URLS: 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!extension->permissions_data()->HasEffectiveAccessToAllHosts()) 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 143