web_request_permissions.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/api/web_request/web_request_permissions.h" 6 7#include "base/string_util.h" 8#include "base/stringprintf.h" 9#include "chrome/browser/extensions/extension_info_map.h" 10#include "chrome/common/extensions/extension.h" 11#include "chrome/common/extensions/extension_constants.h" 12#include "chrome/common/url_constants.h" 13#include "content/public/browser/resource_request_info.h" 14#include "extensions/common/constants.h" 15#include "googleurl/src/gurl.h" 16#include "net/url_request/url_request.h" 17 18using content::ResourceRequestInfo; 19 20namespace { 21 22// Returns true if the URL is sensitive and requests to this URL must not be 23// modified/canceled by extensions, e.g. because it is targeted to the webstore 24// to check for updates, extension blacklisting, etc. 25bool IsSensitiveURL(const GURL& url) { 26 // TODO(battre) Merge this, CanExtensionAccessURL and 27 // Extension::CanExecuteScriptOnPage into one function. 28 bool sensitive_chrome_url = false; 29 const std::string host = url.host(); 30 const char kGoogleCom[] = ".google.com"; 31 const char kClient[] = "clients"; 32 if (EndsWith(host, kGoogleCom, true)) { 33 // Check for "clients[0-9]*.google.com" hosts. 34 // This protects requests to several internal services such as sync, 35 // extension update pings, captive portal detection, fraudulent certificate 36 // reporting, autofill and others. 37 if (StartsWithASCII(host, kClient, true)) { 38 bool match = true; 39 for (std::string::const_iterator i = host.begin() + strlen(kClient), 40 end = host.end() - strlen(kGoogleCom); i != end; ++i) { 41 if (!isdigit(*i)) 42 match = false; 43 } 44 sensitive_chrome_url = sensitive_chrome_url || match; 45 } 46 // This protects requests to safe browsing, link doctor, and possibly 47 // others. 48 sensitive_chrome_url = sensitive_chrome_url || 49 EndsWith(url.host(), ".clients.google.com", true) || 50 url.host() == "sb-ssl.google.com"; 51 } 52 GURL::Replacements replacements; 53 replacements.ClearQuery(); 54 replacements.ClearRef(); 55 GURL url_without_query = url.ReplaceComponents(replacements); 56 return sensitive_chrome_url || 57 extension_urls::IsWebstoreUpdateUrl(url_without_query) || 58 extension_urls::IsBlacklistUpdateUrl(url); 59} 60 61// Returns true if the scheme is one we want to allow extensions to have access 62// to. Extensions still need specific permissions for a given URL, which is 63// covered by CanExtensionAccessURL. 64bool HasWebRequestScheme(const GURL& url) { 65 return (url.SchemeIs(chrome::kAboutScheme) || 66 url.SchemeIs(chrome::kFileScheme) || 67 url.SchemeIs(chrome::kFileSystemScheme) || 68 url.SchemeIs(chrome::kFtpScheme) || 69 url.SchemeIs(chrome::kHttpScheme) || 70 url.SchemeIs(chrome::kHttpsScheme) || 71 url.SchemeIs(extensions::kExtensionScheme)); 72} 73 74} // namespace 75 76// static 77bool WebRequestPermissions::HideRequest( 78 const ExtensionInfoMap* extension_info_map, 79 const net::URLRequest* request) { 80 // Hide requests from the Chrome WebStore App. 81 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); 82 if (info && extension_info_map) { 83 int process_id = info->GetChildID(); 84 const extensions::ProcessMap& process_map = 85 extension_info_map->process_map(); 86 if (process_map.Contains(extension_misc::kWebStoreAppId, process_id)) 87 return true; 88 } 89 90 const GURL& url = request->url(); 91 return IsSensitiveURL(url) || !HasWebRequestScheme(url); 92} 93 94// static 95bool WebRequestPermissions::CanExtensionAccessURL( 96 const ExtensionInfoMap* extension_info_map, 97 const std::string& extension_id, 98 const GURL& url, 99 bool crosses_incognito, 100 bool enforce_host_permissions) { 101 // extension_info_map can be NULL in testing. 102 if (!extension_info_map) 103 return true; 104 105 const extensions::Extension* extension = 106 extension_info_map->extensions().GetByID(extension_id); 107 if (!extension) 108 return false; 109 110 // Check if this event crosses incognito boundaries when it shouldn't. 111 if (crosses_incognito && !extension_info_map->CanCrossIncognito(extension)) 112 return false; 113 114 if (enforce_host_permissions) { 115 // about: URLs are not covered in host permissions, but are allowed anyway. 116 bool host_permissions_ok = (url.SchemeIs(chrome::kAboutScheme) || 117 extension->HasHostPermission(url) || 118 url.GetOrigin() == extension->url()); 119 if (!host_permissions_ok) 120 return false; 121 } 122 123 return true; 124} 125