// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/common/pepper_permission_util.h" #include #include #include "chrome/common/extensions/features/feature_channel.h" #include "components/crx_file/id_util.h" #include "extensions/common/extension_builder.h" #include "extensions/common/extension_set.h" #include "testing/gtest/include/gtest/gtest.h" using chrome::IsExtensionOrSharedModuleWhitelisted; namespace extensions { namespace { // Return an extension with |id| which imports a module with the given // |import_id|. scoped_refptr CreateExtensionImportingModule( const std::string& import_id, const std::string& id) { scoped_ptr manifest = DictionaryBuilder() .Set("name", "Has Dependent Modules") .Set("version", "1.0") .Set("manifest_version", 2) .Set("import", ListBuilder().Append(DictionaryBuilder().Set("id", import_id))) .Build(); return ExtensionBuilder() .SetManifest(manifest.Pass()) .AddFlags(Extension::FROM_WEBSTORE) .SetID(id) .Build(); } } // namespace TEST(PepperPermissionUtilTest, ExtensionWhitelisting) { ScopedCurrentChannel current_channel(chrome::VersionInfo::CHANNEL_UNKNOWN); ExtensionSet extensions; std::string whitelisted_id = crx_file::id_util::GenerateId("whitelisted_extension"); scoped_ptr manifest = DictionaryBuilder() .Set("name", "Whitelisted Extension") .Set("version", "1.0") .Set("manifest_version", 2) .Build(); scoped_refptr ext = ExtensionBuilder() .SetManifest(manifest.Pass()) .SetID(whitelisted_id) .Build(); extensions.Insert(ext); std::set whitelist; std::string url = std::string("chrome-extension://") + whitelisted_id + std::string("/manifest.nmf"); std::string bad_scheme_url = std::string("http://") + whitelisted_id + std::string("/manifest.nmf"); std::string bad_host_url = std::string("chrome-extension://") + crx_file::id_util::GenerateId("bad_host"); std::string("/manifest.nmf"); EXPECT_FALSE( IsExtensionOrSharedModuleWhitelisted(GURL(url), &extensions, whitelist)); whitelist.insert(whitelisted_id); EXPECT_TRUE( IsExtensionOrSharedModuleWhitelisted(GURL(url), &extensions, whitelist)); EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted( GURL(bad_scheme_url), &extensions, whitelist)); EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted( GURL(bad_host_url), &extensions, whitelist)); } TEST(PepperPermissionUtilTest, SharedModuleWhitelisting) { ScopedCurrentChannel current_channel(chrome::VersionInfo::CHANNEL_UNKNOWN); ExtensionSet extensions; std::string whitelisted_id = crx_file::id_util::GenerateId("extension_id"); std::string bad_id = crx_file::id_util::GenerateId("bad_id"); scoped_ptr shared_module_manifest = DictionaryBuilder() .Set("name", "Whitelisted Shared Module") .Set("version", "1.0") .Set("manifest_version", 2) .Set("export", DictionaryBuilder() .Set("resources", ListBuilder().Append("*")) // Add the extension to the whitelist. This // restricts import to |whitelisted_id| only. .Set("whitelist", ListBuilder().Append(whitelisted_id))) .Build(); scoped_refptr shared_module = ExtensionBuilder().SetManifest(shared_module_manifest.Pass()).Build(); scoped_refptr ext = CreateExtensionImportingModule(shared_module->id(), whitelisted_id); std::string extension_url = std::string("chrome-extension://") + ext->id() + std::string("/foo.html"); std::set whitelist; // Important: whitelist *only* the shared module. whitelist.insert(shared_module->id()); extensions.Insert(ext); // This should fail because shared_module is not in the set of extensions. EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted( GURL(extension_url), &extensions, whitelist)); extensions.Insert(shared_module); EXPECT_TRUE(IsExtensionOrSharedModuleWhitelisted( GURL(extension_url), &extensions, whitelist)); scoped_refptr not_in_sm_whitelist = CreateExtensionImportingModule(shared_module->id(), bad_id); std::string not_in_sm_whitelist_url = std::string("chrome-extension://") + not_in_sm_whitelist->id() + std::string("/foo.html"); extensions.Insert(not_in_sm_whitelist); // This should succeed, even though |not_in_sm_whitelist| is not whitelisted // to use shared_module, because the pepper permission utility does not care // about that whitelist. It is possible to install against the whitelist as // an unpacked extension. EXPECT_TRUE(IsExtensionOrSharedModuleWhitelisted( GURL(not_in_sm_whitelist_url), &extensions, whitelist)); // Note that the whitelist should be empty after this call, so tests checking // for failure to import will fail because of this. whitelist.erase(shared_module->id()); EXPECT_FALSE(IsExtensionOrSharedModuleWhitelisted( GURL(extension_url), &extensions, whitelist)); } } // namespace extensions