summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_apitest.cc1
-rw-r--r--chrome/browser/extensions/extension_browsertests_misc.cc66
-rw-r--r--chrome/browser/extensions/extension_protocols.cc52
-rw-r--r--chrome/browser/extensions/extension_resource_request_policy_apitest.cc95
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/renderer/extensions/extension_resource_request_policy.cc63
-rw-r--r--chrome/renderer/extensions/extension_resource_request_policy.h24
-rw-r--r--chrome/renderer/render_view.cc14
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/manifest.json (renamed from chrome/test/data/extensions/origin_privileges/extension/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/test.png (renamed from chrome/test/data/extensions/origin_privileges/extension/test.png)bin275 -> 275 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/can_load_icons_from_hosted_apps.html (renamed from chrome/test/data/extensions/origin_privileges/extension2/can_load_icons_from_hosted_apps.html)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/cant_load_packaged_resources_from_hosted_apps.html (renamed from chrome/test/data/extensions/origin_privileges/extension2/cant_load_packaged_resources_from_hosted_apps.html)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/extensions_can_load_other_extension_resources.html (renamed from chrome/test/data/extensions/origin_privileges/extension2/extensions_can_load_other_extension_resources.html)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/index.html (renamed from chrome/test/data/extensions/origin_privileges/extension2/index.html)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/manifest.json (renamed from chrome/test/data/extensions/origin_privileges/extension2/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/test.png (renamed from chrome/test/data/extensions/origin_privileges/extension2/test.png)bin275 -> 275 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/manifest.json (renamed from chrome/test/data/extensions/origin_privileges/hosted_app/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test.png (renamed from chrome/test/data/extensions/origin_privileges/hosted_app/test.png)bin275 -> 275 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test2.png (renamed from chrome/test/data/extensions/origin_privileges/hosted_app/test2.png)bin275 -> 275 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/index.html (renamed from chrome/test/data/extensions/origin_privileges/index.html)0
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/media/audio.html1
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.wavbin0 -> 188460 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.webmbin0 -> 58199 bytes
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/media/manifest.json4
-rw-r--r--chrome/test/data/extensions/api_test/extension_resource_request_policy/media/video.html3
26 files changed, 213 insertions, 113 deletions
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc
index dbb47cd..8ff88e8 100644
--- a/chrome/browser/extensions/extension_apitest.cc
+++ b/chrome/browser/extensions/extension_apitest.cc
@@ -152,7 +152,6 @@ bool ExtensionApiTest::RunExtensionTestImpl(const char* extension_name,
url = extension->GetResourceURL(page_url);
}
- LOG(ERROR) << "Loading page url: " << url.spec();
ui_test_utils::NavigateToURL(browser(), url);
}
diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc
index 8ceda4d..63d0402 100644
--- a/chrome/browser/extensions/extension_browsertests_misc.cc
+++ b/chrome/browser/extensions/extension_browsertests_misc.cc
@@ -79,72 +79,6 @@ static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
return host;
}
-// Tests that extension resources can be loaded from origins which the
-// extension specifies in permissions but not from others.
-IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, OriginPrivileges) {
- host_resolver()->AddRule("*", "127.0.0.1");
- ASSERT_TRUE(test_server()->Start());
- ASSERT_TRUE(LoadExtension(test_data_dir_
- .AppendASCII("origin_privileges").AppendASCII("extension")));
-
- GURL origin_privileges_index(
- test_server()->GetURL("files/extensions/origin_privileges/index.html"));
-
- std::string host_a("a.com");
- GURL::Replacements make_host_a_com;
- make_host_a_com.SetHostStr(host_a);
-
- std::string host_b("b.com");
- GURL::Replacements make_host_b_com;
- make_host_b_com.SetHostStr(host_b);
-
- // A web host that has permission.
- ui_test_utils::NavigateToURL(
- browser(), origin_privileges_index.ReplaceComponents(make_host_a_com));
- std::string result;
- ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
- browser()->GetSelectedTabContents()->render_view_host(), L"",
- L"window.domAutomationController.send(document.title)",
- &result));
- EXPECT_EQ(result, "Loaded");
-
- // A web host that does not have permission.
- ui_test_utils::NavigateToURL(
- browser(), origin_privileges_index.ReplaceComponents(make_host_b_com));
- ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
- browser()->GetSelectedTabContents()->render_view_host(), L"",
- L"window.domAutomationController.send(document.title)",
- &result));
- EXPECT_EQ(result, "Image failed to load");
-
- // A data URL. Data URLs should always be able to load chrome-extension://
- // resources.
- std::string file_source;
- ASSERT_TRUE(file_util::ReadFileToString(
- test_data_dir_.AppendASCII("origin_privileges")
- .AppendASCII("index.html"), &file_source));
- ui_test_utils::NavigateToURL(browser(),
- GURL(std::string("data:text/html;charset=utf-8,") + file_source));
- ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
- browser()->GetSelectedTabContents()->render_view_host(), L"",
- L"window.domAutomationController.send(document.title)",
- &result));
- EXPECT_EQ(result, "Loaded");
-
- // A different extension. Extensions should always be able to load each
- // other's resources.
- ASSERT_TRUE(LoadExtension(test_data_dir_
- .AppendASCII("origin_privileges").AppendASCII("extension2")));
- ui_test_utils::NavigateToURL(
- browser(),
- GURL("chrome-extension://pbkkcbgdkliohhfaeefcijaghglkahja/index.html"));
- ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
- browser()->GetSelectedTabContents()->render_view_host(), L"",
- L"window.domAutomationController.send(document.title)",
- &result));
- EXPECT_EQ(result, "Loaded");
-}
-
// Tests that we can load extension pages into the tab area and they can call
// extension APIs.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TabContents) {
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 1ee6952..91222c7 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -67,6 +67,8 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
};
// Returns true if an chrome-extension:// resource should be allowed to load.
+// TODO(aa): This should be moved into ExtensionResourceRequestPolicy, but we
+// first need to find a way to get CanLoadInIncognito state into the renderers.
bool AllowExtensionResourceLoad(net::URLRequest* request,
ChromeURLRequestContext* context,
const std::string& scheme) {
@@ -81,27 +83,6 @@ bool AllowExtensionResourceLoad(net::URLRequest* request,
return true;
}
- GURL origin_url(info->frame_origin());
-
- // chrome:// URLs are always allowed to load chrome-extension:// resources.
- // The app launcher in the NTP uses this feature, as does dev tools.
- if (origin_url.SchemeIs(chrome::kChromeDevToolsScheme) ||
- origin_url.SchemeIs(chrome::kChromeUIScheme))
- return true;
-
- // Disallow loading of packaged resources for hosted apps. We don't allow
- // hybrid hosted/packaged apps. The one exception is access to icons, since
- // some extensions want to be able to do things like create their own
- // launchers.
- if (context->extension_info_map()->
- ExtensionHasWebExtent(request->url().host())) {
- if (!context->extension_info_map()->URLIsForExtensionIcon(request->url())) {
- LOG(ERROR) << "Denying load of " << request->url().spec() << " from "
- << "hosted app.";
- return false;
- }
- }
-
// Don't allow toplevel navigations to extension resources in incognito mode.
// This is because an extension must run in a single process, and an
// incognito tab prevents that.
@@ -114,30 +95,7 @@ bool AllowExtensionResourceLoad(net::URLRequest* request,
return false;
}
- // Otherwise, pages are allowed to load resources from extensions if the
- // extension has host permissions to (and therefore could be running script
- // in, which might need access to the extension resources).
- //
- // Exceptions are:
- // - empty origin (needed for some edge cases when we have empty origins)
- // - chrome-extension:// (for legacy reasons -- some extensions interop)
- // - data: (basic HTML notifications use data URLs internally)
- if (origin_url.is_empty() ||
- origin_url.SchemeIs(chrome::kExtensionScheme) |
- origin_url.SchemeIs(chrome::kDataScheme)) {
- return true;
- } else {
- ExtensionExtent host_permissions = context->extension_info_map()->
- GetEffectiveHostPermissionsForExtension(request->url().host());
- if (host_permissions.ContainsURL(origin_url)) {
- return true;
- } else {
- LOG(ERROR) << "Denying load of " << request->url().spec() << " from "
- << origin_url.spec() << " because the extension does not have "
- << "access to the requesting page.";
- return false;
- }
- }
+ return true;
}
} // namespace
@@ -151,8 +109,10 @@ static net::URLRequestJob* CreateExtensionURLRequestJob(
static_cast<ChromeURLRequestContext*>(request->context());
// TODO(mpcomplete): better error code.
- if (!AllowExtensionResourceLoad(request, context, scheme))
+ if (!AllowExtensionResourceLoad(request, context, scheme)) {
+ LOG(ERROR) << "disallowed in extension protocols";
return new net::URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);
+ }
// chrome-extension://extension-id/resource/path.js
const std::string& extension_id = request->url().host();
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
new file mode 100644
index 0000000..b5d45c1
--- /dev/null
+++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2011 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 "base/logging.h"
+#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/ui_test_utils.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/mock_host_resolver.h"
+
+class ExtensionResourceRequestPolicyTest : public ExtensionApiTest {
+};
+
+// Note, this mostly tests the logic of chrome/renderer/extensions/
+// extension_resource_request_policy.*, but we have it as a browser test so that
+// can make sure it works end-to-end.
+IN_PROC_BROWSER_TEST_F(ExtensionResourceRequestPolicyTest, OriginPrivileges) {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(test_server()->Start());
+ ASSERT_TRUE(LoadExtension(test_data_dir_
+ .AppendASCII("extension_resource_request_policy")
+ .AppendASCII("extension")));
+
+ GURL web_resource(
+ test_server()->GetURL(
+ "files/extensions/api_test/extension_resource_request_policy/"
+ "index.html"));
+
+ std::string host_a("a.com");
+ GURL::Replacements make_host_a_com;
+ make_host_a_com.SetHostStr(host_a);
+
+ std::string host_b("b.com");
+ GURL::Replacements make_host_b_com;
+ make_host_b_com.SetHostStr(host_b);
+
+ // A web host that has permission.
+ ui_test_utils::NavigateToURL(
+ browser(), web_resource.ReplaceComponents(make_host_a_com));
+ std::string result;
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"window.domAutomationController.send(document.title)",
+ &result));
+ EXPECT_EQ(result, "Loaded");
+
+ // A web host that does not have permission.
+ ui_test_utils::NavigateToURL(
+ browser(), web_resource.ReplaceComponents(make_host_b_com));
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"window.domAutomationController.send(document.title)",
+ &result));
+ EXPECT_EQ(result, "Image failed to load");
+
+ // A data URL. Data URLs should always be able to load chrome-extension://
+ // resources.
+ std::string file_source;
+ ASSERT_TRUE(file_util::ReadFileToString(
+ test_data_dir_.AppendASCII("extension_resource_request_policy")
+ .AppendASCII("index.html"), &file_source));
+ ui_test_utils::NavigateToURL(browser(),
+ GURL(std::string("data:text/html;charset=utf-8,") + file_source));
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"window.domAutomationController.send(document.title)",
+ &result));
+ EXPECT_EQ(result, "Loaded");
+
+ // A different extension. Extensions should always be able to load each
+ // other's resources.
+ ASSERT_TRUE(LoadExtension(test_data_dir_
+ .AppendASCII("extension_resource_request_policy")
+ .AppendASCII("extension2")));
+ ui_test_utils::NavigateToURL(
+ browser(),
+ GURL("chrome-extension://pbkkcbgdkliohhfaeefcijaghglkahja/index.html"));
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"window.domAutomationController.send(document.title)",
+ &result));
+ EXPECT_EQ(result, "Loaded");
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionResourceRequestPolicyTest, Audio) {
+ EXPECT_TRUE(RunExtensionSubtest("extension_resource_request_policy/media",
+ "audio.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionResourceRequestPolicyTest, Video) {
+ EXPECT_TRUE(RunExtensionSubtest("extension_resource_request_policy/media",
+ "video.html"));
+}
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 055645b..54f315a 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -60,6 +60,8 @@
'renderer/extensions/event_bindings.h',
'renderer/extensions/extension_process_bindings.cc',
'renderer/extensions/extension_process_bindings.h',
+ 'renderer/extensions/extension_resource_request_policy.cc',
+ 'renderer/extensions/extension_resource_request_policy.h',
'renderer/extensions/js_only_v8_extensions.cc',
'renderer/extensions/js_only_v8_extensions.h',
'renderer/extensions/renderer_extension_bindings.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index c46805b..f52e3ed 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2136,6 +2136,7 @@
'browser/extensions/extension_popup_apitest.cc',
'browser/extensions/extension_proxy_apitest.cc',
'browser/extensions/extension_processes_apitest.cc',
+ 'browser/extensions/extension_resource_request_policy_apitest.cc',
'browser/extensions/extension_rlz_apitest.cc',
'browser/extensions/extension_sidebar_apitest.cc',
'browser/extensions/extension_startup_browsertest.cc',
diff --git a/chrome/renderer/extensions/extension_resource_request_policy.cc b/chrome/renderer/extensions/extension_resource_request_policy.cc
new file mode 100644
index 0000000..f4fcb30
--- /dev/null
+++ b/chrome/renderer/extensions/extension_resource_request_policy.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2011 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/renderer/extensions/extension_resource_request_policy.h"
+
+#include "base/logging.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_set.h"
+#include "googleurl/src/gurl.h"
+
+// static
+bool ExtensionResourceRequestPolicy::CanRequestResource(
+ const GURL& resource_url,
+ const GURL& frame_url,
+ const ExtensionSet* loaded_extensions) {
+ CHECK(resource_url.SchemeIs(chrome::kExtensionScheme));
+
+ // chrome:// URLs are always allowed to load chrome-extension:// resources.
+ // The app launcher in the NTP uses this feature, as does dev tools.
+ if (frame_url.SchemeIs(chrome::kChromeDevToolsScheme) ||
+ frame_url.SchemeIs(chrome::kChromeUIScheme))
+ return true;
+
+ // Disallow loading of packaged resources for hosted apps. We don't allow
+ // hybrid hosted/packaged apps. The one exception is access to icons, since
+ // some extensions want to be able to do things like create their own
+ // launchers.
+ const Extension* extension = loaded_extensions->GetByURL(resource_url);
+ if (extension && extension->is_hosted_app() &&
+ !extension->icons().ContainsPath(resource_url.path())) {
+ LOG(ERROR) << "Denying load of " << resource_url.spec() << " from "
+ << "hosted app.";
+ return false;
+ }
+
+ // Otherwise, pages are allowed to load resources from extensions if the
+ // extension has host permissions to (and therefore could be running script
+ // in, which might need access to the extension resources).
+ //
+ // Exceptions are:
+ // - empty origin (needed for some edge cases when we have empty origins)
+ // - chrome-extension:// (for legacy reasons -- some extensions interop)
+ // - data: (basic HTML notifications use data URLs internally)
+ if (frame_url.is_empty() ||
+ frame_url.SchemeIs(chrome::kExtensionScheme) |
+ frame_url.SchemeIs(chrome::kDataScheme)) {
+ return true;
+ } else {
+ if (extension->GetEffectiveHostPermissions().ContainsURL(frame_url)) {
+ return true;
+ } else {
+ LOG(ERROR) << "Denying load of " << resource_url.spec() << " from "
+ << frame_url.spec() << " because the extension does not have "
+ << "access to the requesting page.";
+ return false;
+ }
+ }
+}
+
+ExtensionResourceRequestPolicy::ExtensionResourceRequestPolicy() {
+}
diff --git a/chrome/renderer/extensions/extension_resource_request_policy.h b/chrome/renderer/extensions/extension_resource_request_policy.h
new file mode 100644
index 0000000..adfc816
--- /dev/null
+++ b/chrome/renderer/extensions/extension_resource_request_policy.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2011 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.
+
+#ifndef CHROME_RENDERER_EXTENSIONS_EXTENSION_RESOURCE_REQUEST_POLICY_H_
+#define CHROME_RENDERER_EXTENSIONS_EXTENSION_RESOURCE_REQUEST_POLICY_H_
+#pragma once
+
+class ExtensionSet;
+class GURL;
+
+// Encapsulates the policy for when chrome-extension:// URLs can be requested.
+class ExtensionResourceRequestPolicy {
+ public:
+ // Returns true if the |resource_url| can be requested from |frame_url|.
+ static bool CanRequestResource(const GURL& resource_url,
+ const GURL& frame_url,
+ const ExtensionSet* loaded_extensions);
+
+ private:
+ ExtensionResourceRequestPolicy();
+};
+
+#endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_RESOURCE_REQUEST_POLICY_H_
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 9ea2b85..8372ad3 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -61,6 +61,7 @@
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
+#include "chrome/renderer/extensions/extension_resource_request_policy.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/external_popup_menu.h"
@@ -3616,6 +3617,19 @@ void RenderView::willSendRequest(
WebDataSource* top_data_source = top_frame->dataSource();
WebDataSource* data_source =
provisional_data_source ? provisional_data_source : top_data_source;
+
+ // If the request is for an extension resource, check whether it should be
+ // allowed. If not allowed, we reset the URL to something invalid to prevent
+ // the request and cause an error.
+ GURL request_url(request.url());
+ if (request_url.SchemeIs(chrome::kExtensionScheme) &&
+ !ExtensionResourceRequestPolicy::CanRequestResource(
+ request_url,
+ GURL(frame->url()),
+ render_thread_->GetExtensions())) {
+ request.setURL(WebURL(GURL("chrome-extension://invalid/")));
+ }
+
if (data_source) {
NavigationState* state = NavigationState::FromDataSource(data_source);
if (state && state->is_cache_policy_override_set())
diff --git a/chrome/test/data/extensions/origin_privileges/extension/manifest.json b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/manifest.json
index 3a0c184..3a0c184 100644
--- a/chrome/test/data/extensions/origin_privileges/extension/manifest.json
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/manifest.json
diff --git a/chrome/test/data/extensions/origin_privileges/extension/test.png b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/test.png
index 4421311..4421311 100644
--- a/chrome/test/data/extensions/origin_privileges/extension/test.png
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension/test.png
Binary files differ
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/can_load_icons_from_hosted_apps.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/can_load_icons_from_hosted_apps.html
index 46c6a70..46c6a70 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/can_load_icons_from_hosted_apps.html
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/can_load_icons_from_hosted_apps.html
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/cant_load_packaged_resources_from_hosted_apps.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/cant_load_packaged_resources_from_hosted_apps.html
index 9ba959d..9ba959d 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/cant_load_packaged_resources_from_hosted_apps.html
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/cant_load_packaged_resources_from_hosted_apps.html
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/extensions_can_load_other_extension_resources.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/extensions_can_load_other_extension_resources.html
index 4183769..4183769 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/extensions_can_load_other_extension_resources.html
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/extensions_can_load_other_extension_resources.html
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/index.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/index.html
index 4183769..4183769 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/index.html
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/index.html
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/manifest.json b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/manifest.json
index 970fcf0..970fcf0 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/manifest.json
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/manifest.json
diff --git a/chrome/test/data/extensions/origin_privileges/extension2/test.png b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/test.png
index 4421311..4421311 100644
--- a/chrome/test/data/extensions/origin_privileges/extension2/test.png
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/extension2/test.png
Binary files differ
diff --git a/chrome/test/data/extensions/origin_privileges/hosted_app/manifest.json b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/manifest.json
index 4de0837..4de0837 100644
--- a/chrome/test/data/extensions/origin_privileges/hosted_app/manifest.json
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/manifest.json
diff --git a/chrome/test/data/extensions/origin_privileges/hosted_app/test.png b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test.png
index 4421311..4421311 100644
--- a/chrome/test/data/extensions/origin_privileges/hosted_app/test.png
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test.png
Binary files differ
diff --git a/chrome/test/data/extensions/origin_privileges/hosted_app/test2.png b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test2.png
index 4421311..4421311 100644
--- a/chrome/test/data/extensions/origin_privileges/hosted_app/test2.png
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/hosted_app/test2.png
Binary files differ
diff --git a/chrome/test/data/extensions/origin_privileges/index.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/index.html
index 4183769..4183769 100644
--- a/chrome/test/data/extensions/origin_privileges/index.html
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/index.html
diff --git a/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/audio.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/audio.html
new file mode 100644
index 0000000..8ef69f4
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/audio.html
@@ -0,0 +1 @@
+<audio src="bear.wav" oncanplay="chrome.test.notifyPass()">
diff --git a/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.wav b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.wav
new file mode 100644
index 0000000..1870eed
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.wav
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.webm b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.webm
new file mode 100644
index 0000000..422df3f
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/bear.webm
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/manifest.json b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/manifest.json
new file mode 100644
index 0000000..0d9792a
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "test",
+ "version": "1"
+}
diff --git a/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/video.html b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/video.html
new file mode 100644
index 0000000..dfa951c
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/extension_resource_request_policy/media/video.html
@@ -0,0 +1,3 @@
+<!-- The display:none is a workaround for crbug.com/71905 -->
+<video src="bear.webm" oncanplay="chrome.test.notifyPass()"
+ style="display:none">