Commit ea2dc902 authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

Extensions: Add ability to check host permissions for initiator as well.

This CL adds the ability to check for host permission access to both the request
url and its initiator. WebRequestPermissions::REQUIRE_HOST_PERMISSION is renamed
to WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL and
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR is
introduced. This will subsequently be used to check access for the Declarative
Net Request API.

BUG=777714, 696822

Change-Id: I8ec9b08be1e8eb240e28328b7c254055e63005f3
Reviewed-on: https://chromium-review.googlesource.com/905405
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#534924}
parent 33c5e0a9
......@@ -193,6 +193,7 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, TestHideRequestForURL) {
TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
TestCanExtensionAccessURL_HostPermissions) {
// Request with empty initiator.
std::unique_ptr<net::URLRequest> request(
context.CreateRequest(GURL("http://example.com"), net::DEFAULT_PRIORITY,
NULL, TRAFFIC_ANNOTATION_FOR_TESTS));
......@@ -211,15 +212,23 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request->initiator()));
EXPECT_EQ(PermissionsData::ACCESS_ALLOWED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(), request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request->initiator()));
EXPECT_EQ(
PermissionsData::ACCESS_ALLOWED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(), request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR,
request->initiator()));
EXPECT_EQ(PermissionsData::ACCESS_DENIED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(), request->url(),
......@@ -227,6 +236,54 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
false, // crosses_incognito
WebRequestPermissions::REQUIRE_ALL_URLS, request->initiator()));
std::unique_ptr<net::URLRequest> request_with_initiator(
context.CreateRequest(GURL("http://example.com"), net::DEFAULT_PRIORITY,
nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
request_with_initiator->set_initiator(
url::Origin::Create(GURL("http://www.example.org")));
EXPECT_EQ(PermissionsData::ACCESS_ALLOWED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), permissionless_extension_->id(),
request_with_initiator->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::DO_NOT_CHECK_HOST,
request_with_initiator->initiator()));
EXPECT_EQ(PermissionsData::ACCESS_DENIED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), permissionless_extension_->id(),
request_with_initiator->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request_with_initiator->initiator()));
EXPECT_EQ(PermissionsData::ACCESS_ALLOWED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(),
request_with_initiator->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request_with_initiator->initiator()));
EXPECT_EQ(
PermissionsData::ACCESS_DENIED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(),
request_with_initiator->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR,
request_with_initiator->initiator()));
EXPECT_EQ(PermissionsData::ACCESS_DENIED,
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map_.get(), com_extension_->id(),
request_with_initiator->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_ALL_URLS,
request_with_initiator->initiator()));
// Public Sessions tests.
#if defined(OS_CHROMEOS)
std::unique_ptr<net::URLRequest> org_request(context.CreateRequest(
......@@ -239,7 +296,7 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
org_request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
org_request->initiator()));
chromeos::ScopedTestPublicSessionLoginState login_state;
......@@ -252,7 +309,7 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
org_request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
org_request->initiator()));
EXPECT_EQ(
......@@ -275,7 +332,7 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest,
chrome_request->url(),
-1, // No tab id.
false, // crosses_incognito
WebRequestPermissions::REQUIRE_HOST_PERMISSION,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
chrome_request->initiator()));
#endif
}
......@@ -501,7 +501,7 @@ bool WebRequestAction::HasPermission(ApplyInfo* apply_info,
permission_check = WebRequestPermissions::DO_NOT_CHECK_HOST;
break;
case STRATEGY_HOST:
permission_check = WebRequestPermissions::REQUIRE_HOST_PERMISSION;
permission_check = WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL;
break;
}
// TODO(devlin): Pass in the real tab id here.
......
......@@ -1360,7 +1360,8 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
WebRequestPermissions::CanExtensionAccessURL(
extension_info_map, listener->id.extension_id, request->url,
request->frame_data ? request->frame_data->tab_id : -1,
crosses_incognito, WebRequestPermissions::REQUIRE_HOST_PERMISSION,
crosses_incognito,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL,
request->initiator);
if (access != PermissionsData::ACCESS_ALLOWED) {
......
......@@ -42,6 +42,42 @@ bool HasWebRequestScheme(const GURL& url) {
bool g_allow_all_extension_locations_in_public_session = false;
PermissionsData::AccessType GetHostAccessForURL(
const extensions::Extension& extension,
const GURL& url,
int tab_id) {
// about: URLs are not covered in host permissions, but are allowed
// anyway.
if (url.SchemeIs(url::kAboutScheme) ||
url::IsSameOriginWith(url, extension.url())) {
return PermissionsData::ACCESS_ALLOWED;
}
return extension.permissions_data()->GetPageAccess(&extension, url, tab_id,
nullptr /*error*/);
}
// Returns the most restricted access type out of |access1| and |access2|.
PermissionsData::AccessType GetMinimumAccessType(
PermissionsData::AccessType access1,
PermissionsData::AccessType access2) {
PermissionsData::AccessType access = PermissionsData::ACCESS_DENIED;
switch (access1) {
case PermissionsData::ACCESS_DENIED:
access = PermissionsData::ACCESS_DENIED;
break;
case PermissionsData::ACCESS_WITHHELD:
access = (access2 == PermissionsData::ACCESS_DENIED
? PermissionsData::ACCESS_DENIED
: PermissionsData::ACCESS_WITHHELD);
break;
case PermissionsData::ACCESS_ALLOWED:
access = access2;
break;
}
return access;
}
} // namespace
// Returns true if the URL is sensitive and requests to this URL must not be
......@@ -208,17 +244,19 @@ PermissionsData::AccessType WebRequestPermissions::CanExtensionAccessURL(
case DO_NOT_CHECK_HOST:
access = PermissionsData::ACCESS_ALLOWED;
break;
case REQUIRE_HOST_PERMISSION:
// about: URLs are not covered in host permissions, but are allowed
// anyway.
if (url.SchemeIs(url::kAboutScheme) ||
url::IsSameOriginWith(url, extension->url())) {
access = PermissionsData::ACCESS_ALLOWED;
break;
}
access = extension->permissions_data()->GetPageAccess(extension, url,
tab_id, nullptr);
case REQUIRE_HOST_PERMISSION_FOR_URL:
access = GetHostAccessForURL(*extension, url, tab_id);
break;
case REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR: {
PermissionsData::AccessType request_access =
GetHostAccessForURL(*extension, url, tab_id);
PermissionsData::AccessType initiator_access =
initiator
? GetHostAccessForURL(*extension, initiator->GetURL(), tab_id)
: PermissionsData::ACCESS_ALLOWED;
access = GetMinimumAccessType(request_access, initiator_access);
break;
}
case REQUIRE_ALL_URLS:
if (extension->permissions_data()->HasEffectiveAccessToAllHosts())
access = PermissionsData::ACCESS_ALLOWED;
......@@ -240,8 +278,8 @@ bool WebRequestPermissions::CanExtensionAccessInitiator(
if (initiator) {
access = CanExtensionAccessURL(
extension_info_map, extension_id, initiator->GetURL(), tab_id,
crosses_incognito, WebRequestPermissions::REQUIRE_HOST_PERMISSION,
base::nullopt);
crosses_incognito,
WebRequestPermissions::REQUIRE_HOST_PERMISSION_FOR_URL, base::nullopt);
}
return access == PermissionsData::ACCESS_ALLOWED;
}
......@@ -29,9 +29,13 @@ class WebRequestPermissions {
public:
// Different host permission checking modes for CanExtensionAccessURL.
enum HostPermissionsCheck {
DO_NOT_CHECK_HOST = 0, // No check.
REQUIRE_HOST_PERMISSION, // Permission needed for given URL.
REQUIRE_ALL_URLS // Permission needed for <all_urls>.
DO_NOT_CHECK_HOST = 0, // No check.
REQUIRE_HOST_PERMISSION_FOR_URL, // Permission needed for given request
// URL.
REQUIRE_HOST_PERMISSION_FOR_URL_AND_INITIATOR, // Permission needed for
// given request URL and its
// initiator.
REQUIRE_ALL_URLS // Permission needed for <all_urls>.
};
// Returns true if the request shall not be reported to extensions.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment