Home | History | Annotate | Download | only in web_request
      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 "extensions/browser/api/web_request/web_request_permissions.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "chrome/common/extensions/extension_test_util.h"
     10 #include "content/public/browser/resource_request_info.h"
     11 #include "content/public/test/test_browser_thread_bundle.h"
     12 #include "extensions/browser/info_map.h"
     13 #include "extensions/common/constants.h"
     14 #include "ipc/ipc_message.h"
     15 #include "net/base/request_priority.h"
     16 #include "net/url_request/url_request.h"
     17 #include "net/url_request/url_request_test_util.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using content::ResourceRequestInfo;
     21 using content::ResourceType;
     22 using extensions::Extension;
     23 using extensions::Manifest;
     24 using extension_test_util::LoadManifestUnchecked;
     25 
     26 class ExtensionWebRequestHelpersTestWithThreadsTest : public testing::Test {
     27  public:
     28   ExtensionWebRequestHelpersTestWithThreadsTest()
     29       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
     30 
     31  protected:
     32   virtual void SetUp() OVERRIDE;
     33 
     34  protected:
     35   net::TestURLRequestContext context;
     36 
     37   // This extension has Web Request permissions, but no host permission.
     38   scoped_refptr<Extension> permissionless_extension_;
     39   // This extension has Web Request permissions, and *.com a host permission.
     40   scoped_refptr<Extension> com_extension_;
     41   scoped_refptr<extensions::InfoMap> extension_info_map_;
     42 
     43  private:
     44   content::TestBrowserThreadBundle thread_bundle_;
     45 };
     46 
     47 void ExtensionWebRequestHelpersTestWithThreadsTest::SetUp() {
     48   testing::Test::SetUp();
     49 
     50   std::string error;
     51   permissionless_extension_ = LoadManifestUnchecked("permissions",
     52                                                     "web_request_no_host.json",
     53                                                     Manifest::INVALID_LOCATION,
     54                                                     Extension::NO_FLAGS,
     55                                                     "ext_id_1",
     56                                                     &error);
     57   ASSERT_TRUE(permissionless_extension_.get()) << error;
     58   com_extension_ =
     59       LoadManifestUnchecked("permissions",
     60                             "web_request_com_host_permissions.json",
     61                             Manifest::INVALID_LOCATION,
     62                             Extension::NO_FLAGS,
     63                             "ext_id_2",
     64                             &error);
     65   ASSERT_TRUE(com_extension_.get()) << error;
     66   extension_info_map_ = new extensions::InfoMap;
     67   extension_info_map_->AddExtension(permissionless_extension_.get(),
     68                                     base::Time::Now(),
     69                                     false /*incognito_enabled*/,
     70                                     false /*notifications_disabled*/);
     71   extension_info_map_->AddExtension(
     72       com_extension_.get(),
     73       base::Time::Now(),
     74       false /*incognito_enabled*/,
     75       false /*notifications_disabled*/);
     76 }
     77 
     78 TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, TestHideRequestForURL) {
     79   net::TestURLRequestContext context;
     80   const char* sensitive_urls[] = {
     81       "http://clients2.google.com",
     82       "http://clients22.google.com",
     83       "https://clients2.google.com",
     84       "http://clients2.google.com/service/update2/crx",
     85       "https://clients.google.com",
     86       "https://test.clients.google.com",
     87       "https://clients2.google.com/service/update2/crx",
     88       "http://www.gstatic.com/chrome/extensions/blacklist",
     89       "https://www.gstatic.com/chrome/extensions/blacklist",
     90       "notregisteredscheme://www.foobar.com",
     91       "https://chrome.google.com/webstore/",
     92       "https://chrome.google.com/webstore/"
     93           "inlineinstall/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo"
     94   };
     95   const char* non_sensitive_urls[] = {
     96       "http://www.google.com/"
     97   };
     98   const int kSigninProcessId = 99;
     99   extension_info_map_->SetSigninProcess(kSigninProcessId);
    100 
    101   // Check that requests are rejected based on the destination
    102   for (size_t i = 0; i < arraysize(sensitive_urls); ++i) {
    103     GURL sensitive_url(sensitive_urls[i]);
    104     scoped_ptr<net::URLRequest> request(context.CreateRequest(
    105         sensitive_url, net::DEFAULT_PRIORITY, NULL, NULL));
    106     EXPECT_TRUE(WebRequestPermissions::HideRequest(
    107         extension_info_map_.get(), request.get())) << sensitive_urls[i];
    108   }
    109   // Check that requests are accepted if they don't touch sensitive urls.
    110   for (size_t i = 0; i < arraysize(non_sensitive_urls); ++i) {
    111     GURL non_sensitive_url(non_sensitive_urls[i]);
    112     scoped_ptr<net::URLRequest> request(context.CreateRequest(
    113         non_sensitive_url, net::DEFAULT_PRIORITY, NULL, NULL));
    114     EXPECT_FALSE(WebRequestPermissions::HideRequest(
    115         extension_info_map_.get(), request.get())) << non_sensitive_urls[i];
    116   }
    117 
    118   // Check protection of requests originating from the frame showing the Chrome
    119   // WebStore.
    120   // Normally this request is not protected:
    121   GURL non_sensitive_url("http://www.google.com/test.js");
    122   scoped_ptr<net::URLRequest> non_sensitive_request(context.CreateRequest(
    123       non_sensitive_url, net::DEFAULT_PRIORITY, NULL, NULL));
    124   EXPECT_FALSE(WebRequestPermissions::HideRequest(
    125       extension_info_map_.get(), non_sensitive_request.get()));
    126   // If the origin is labeled by the WebStoreAppId, it becomes protected.
    127   {
    128     int process_id = 42;
    129     int site_instance_id = 23;
    130     int view_id = 17;
    131     scoped_ptr<net::URLRequest> sensitive_request(context.CreateRequest(
    132         non_sensitive_url, net::DEFAULT_PRIORITY, NULL, NULL));
    133     ResourceRequestInfo::AllocateForTesting(sensitive_request.get(),
    134                                             content::RESOURCE_TYPE_SCRIPT,
    135                                             NULL,
    136                                             process_id,
    137                                             view_id,
    138                                             MSG_ROUTING_NONE,
    139                                             false);
    140     extension_info_map_->RegisterExtensionProcess(
    141         extensions::kWebStoreAppId, process_id, site_instance_id);
    142     EXPECT_TRUE(WebRequestPermissions::HideRequest(
    143         extension_info_map_.get(), sensitive_request.get()));
    144   }
    145   // If the process is the signin process, it becomes protected.
    146   {
    147     int process_id = kSigninProcessId;
    148     int view_id = 19;
    149     scoped_ptr<net::URLRequest> sensitive_request(context.CreateRequest(
    150         non_sensitive_url, net::DEFAULT_PRIORITY, NULL, NULL));
    151     ResourceRequestInfo::AllocateForTesting(sensitive_request.get(),
    152                                             content::RESOURCE_TYPE_SCRIPT,
    153                                             NULL,
    154                                             process_id,
    155                                             view_id,
    156                                             MSG_ROUTING_NONE,
    157                                             false);
    158     EXPECT_TRUE(WebRequestPermissions::HideRequest(
    159         extension_info_map_.get(), sensitive_request.get()));
    160   }
    161 }
    162 
    163 TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
    164        TestCanExtensionAccessURL_HostPermissions) {
    165   scoped_ptr<net::URLRequest> request(context.CreateRequest(
    166       GURL("http://example.com"), net::DEFAULT_PRIORITY, NULL, NULL));
    167 
    168   EXPECT_TRUE(WebRequestPermissions::CanExtensionAccessURL(
    169       extension_info_map_.get(),
    170       permissionless_extension_->id(),
    171       request->url(),
    172       false /*crosses_incognito*/,
    173       WebRequestPermissions::DO_NOT_CHECK_HOST));
    174   EXPECT_FALSE(WebRequestPermissions::CanExtensionAccessURL(
    175       extension_info_map_.get(),
    176       permissionless_extension_->id(),
    177       request->url(),
    178       false /*crosses_incognito*/,
    179       WebRequestPermissions::REQUIRE_HOST_PERMISSION));
    180   EXPECT_TRUE(WebRequestPermissions::CanExtensionAccessURL(
    181       extension_info_map_.get(),
    182       com_extension_->id(),
    183       request->url(),
    184       false /*crosses_incognito*/,
    185       WebRequestPermissions::REQUIRE_HOST_PERMISSION));
    186   EXPECT_FALSE(WebRequestPermissions::CanExtensionAccessURL(
    187       extension_info_map_.get(),
    188       com_extension_->id(),
    189       request->url(),
    190       false /*crosses_incognito*/,
    191       WebRequestPermissions::REQUIRE_ALL_URLS));
    192 }
    193