Commit 7f105984 authored by Takashi Toyoshima's avatar Takashi Toyoshima Committed by Commit Bot

OOR-CORS: Use CorsOriginAccessMatchMode in CorsOriginPattern

This patch makes mojom::CorsOriginPattern use CorsORiginAccessMatchMode
and allows network::cors::OriginAccessList to create equivalent
mojom::CorsOriginAccessPatterns array.

Also this patch enforces not to rely on cors_origin_patterns.mojom.h
indirectly from Blink platform.

Bug: 908324, 908756
Change-Id: If059a460b424025376b2e4d4433ba6ec17523357
Reviewed-on: https://chromium-review.googlesource.com/c/1350689
Commit-Queue: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611603}
parent 964cc812
...@@ -285,7 +285,7 @@ void ChromeExtensionsClient::AddOriginAccessPermissions( ...@@ -285,7 +285,7 @@ void ChromeExtensionsClient::AddOriginAccessPermissions(
is_extension_active) { is_extension_active) {
origin_patterns->push_back(network::mojom::CorsOriginPattern::New( origin_patterns->push_back(network::mojom::CorsOriginPattern::New(
content::kChromeUIScheme, chrome::kChromeUIThemeHost, content::kChromeUIScheme, chrome::kChromeUIThemeHost,
false /*allow_destination_subdomains*/, network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
network::mojom::CorsOriginAccessMatchPriority::kMaxPriority)); network::mojom::CorsOriginAccessMatchPriority::kMaxPriority));
} }
...@@ -296,7 +296,7 @@ void ChromeExtensionsClient::AddOriginAccessPermissions( ...@@ -296,7 +296,7 @@ void ChromeExtensionsClient::AddOriginAccessPermissions(
extensions::APIPermission::kManagement)) { extensions::APIPermission::kManagement)) {
origin_patterns->push_back(network::mojom::CorsOriginPattern::New( origin_patterns->push_back(network::mojom::CorsOriginPattern::New(
content::kChromeUIScheme, chrome::kChromeUIExtensionIconHost, content::kChromeUIScheme, chrome::kChromeUIExtensionIconHost,
false /*allow_destination_subdomains*/, network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority)); network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority));
} }
} }
......
...@@ -32,6 +32,11 @@ namespace content { ...@@ -32,6 +32,11 @@ namespace content {
namespace { namespace {
const auto kAllowSubdomains =
network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains;
const auto kDisallowSubdomains =
network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains;
const char kTestPath[] = "/loader/cors_origin_access_list_test.html"; const char kTestPath[] = "/loader/cors_origin_access_list_test.html";
const char kTestHost[] = "crossorigin.example.com"; const char kTestHost[] = "crossorigin.example.com";
...@@ -101,10 +106,10 @@ class CorsOriginAccessListBrowserTest ...@@ -101,10 +106,10 @@ class CorsOriginAccessListBrowserTest
void SetAllowList(const std::string& scheme, void SetAllowList(const std::string& scheme,
const std::string& host, const std::string& host,
bool allow_subdomains) { network::mojom::CorsOriginAccessMatchMode mode) {
std::vector<network::mojom::CorsOriginPatternPtr> list1; std::vector<network::mojom::CorsOriginPatternPtr> list1;
list1.push_back(network::mojom::CorsOriginPattern::New( list1.push_back(network::mojom::CorsOriginPattern::New(
scheme, host, allow_subdomains, scheme, host, mode,
network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority)); network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority));
bool first_list_done = false; bool first_list_done = false;
BrowserContext::SetCorsOriginAccessListsForOrigin( BrowserContext::SetCorsOriginAccessListsForOrigin(
...@@ -116,7 +121,7 @@ class CorsOriginAccessListBrowserTest ...@@ -116,7 +121,7 @@ class CorsOriginAccessListBrowserTest
std::vector<network::mojom::CorsOriginPatternPtr> list2; std::vector<network::mojom::CorsOriginPatternPtr> list2;
list2.push_back(network::mojom::CorsOriginPattern::New( list2.push_back(network::mojom::CorsOriginPattern::New(
scheme, host, allow_subdomains, scheme, host, mode,
network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority)); network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority));
bool second_list_done = false; bool second_list_done = false;
BrowserContext::SetCorsOriginAccessListsForOrigin( BrowserContext::SetCorsOriginAccessListsForOrigin(
...@@ -162,7 +167,7 @@ class CorsOriginAccessListBrowserTest ...@@ -162,7 +167,7 @@ class CorsOriginAccessListBrowserTest
// Tests if specifying only protocol allows all hosts to pass. // Tests if specifying only protocol allows all hosts to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
SetAllowList("http", "", true); SetAllowList("http", "", kAllowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE( EXPECT_TRUE(
...@@ -173,7 +178,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) { ...@@ -173,7 +178,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
// Tests if specifying only protocol allows all IP address based hosts to pass. // Tests if specifying only protocol allows all IP address based hosts to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
SetAllowList("http", "", true); SetAllowList("http", "", kAllowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
...@@ -185,7 +190,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) { ...@@ -185,7 +190,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
// Tests if complete allow list set allows only exactly matched host to pass. // Tests if complete allow list set allows only exactly matched host to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
SetAllowList("http", kTestHost, false); SetAllowList("http", kTestHost, kDisallowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE( EXPECT_TRUE(
...@@ -198,7 +203,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) { ...@@ -198,7 +203,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
// case insensitive way to pass. // case insensitive way to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
AllowExactHostInCaseInsensitive) { AllowExactHostInCaseInsensitive) {
SetAllowList("http", kTestHost, false); SetAllowList("http", kTestHost, kDisallowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
...@@ -210,7 +215,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, ...@@ -210,7 +215,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
// Tests if complete allow list set does not allow a host with a different port // Tests if complete allow list set does not allow a host with a different port
// to pass. // to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
SetAllowList("http", kTestHost, false); SetAllowList("http", kTestHost, kDisallowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
...@@ -221,7 +226,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) { ...@@ -221,7 +226,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
// Tests if complete allow list set allows a subdomain to pass if it is allowed. // Tests if complete allow list set allows a subdomain to pass if it is allowed.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
SetAllowList("http", kTestHost, true); SetAllowList("http", kTestHost, kAllowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
...@@ -232,7 +237,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) { ...@@ -232,7 +237,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
// Tests if complete allow list set does not allow a subdomain to pass. // Tests if complete allow list set does not allow a subdomain to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) { IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
SetAllowList("http", kTestHost, false); SetAllowList("http", kTestHost, kDisallowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
...@@ -245,7 +250,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) { ...@@ -245,7 +250,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
// protocol to pass. // protocol to pass.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
BlockDifferentProtocol) { BlockDifferentProtocol) {
SetAllowList("https", kTestHost, false); SetAllowList("https", kTestHost, kDisallowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE( EXPECT_TRUE(
...@@ -257,7 +262,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, ...@@ -257,7 +262,7 @@ IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
// Tests if IP address based hosts should not follow subdomain match rules. // Tests if IP address based hosts should not follow subdomain match rules.
IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
SubdomainMatchShouldNotBeAppliedForIPAddress) { SubdomainMatchShouldNotBeAppliedForIPAddress) {
SetAllowList("http", "*.0.0.1", true); SetAllowList("http", "*.0.0.1", kAllowSubdomains);
std::unique_ptr<TitleWatcher> watcher = CreateWatcher(); std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL( EXPECT_TRUE(NavigateToURL(
......
...@@ -37,7 +37,11 @@ void AddURLPatternSetToList( ...@@ -37,7 +37,11 @@ void AddURLPatternSetToList(
if (!pattern.MatchesScheme(scheme)) if (!pattern.MatchesScheme(scheme))
continue; continue;
list->push_back(network::mojom::CorsOriginPattern::New( list->push_back(network::mojom::CorsOriginPattern::New(
scheme, pattern.host(), pattern.match_subdomains(), priority)); scheme, pattern.host(),
pattern.match_subdomains()
? network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains
: network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
priority));
} }
} }
} }
...@@ -80,7 +84,8 @@ CreateCorsOriginAccessBlockList(const Extension& extension) { ...@@ -80,7 +84,8 @@ CreateCorsOriginAccessBlockList(const Extension& extension) {
GURL webstore_launch_url = extension_urls::GetWebstoreLaunchURL(); GURL webstore_launch_url = extension_urls::GetWebstoreLaunchURL();
block_list.push_back(network::mojom::CorsOriginPattern::New( block_list.push_back(network::mojom::CorsOriginPattern::New(
webstore_launch_url.scheme(), webstore_launch_url.host(), true, webstore_launch_url.scheme(), webstore_launch_url.host(),
network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains,
network::mojom::CorsOriginAccessMatchPriority::kHighPriority)); network::mojom::CorsOriginAccessMatchPriority::kHighPriority));
// TODO(devlin): Should we also block the webstore update URL here? See // TODO(devlin): Should we also block the webstore update URL here? See
......
...@@ -1238,14 +1238,18 @@ void Dispatcher::UpdateOriginPermissions(const Extension& extension) { ...@@ -1238,14 +1238,18 @@ void Dispatcher::UpdateOriginPermissions(const Extension& extension) {
for (const auto& entry : allow_list) { for (const auto& entry : allow_list) {
WebSecurityPolicy::AddOriginAccessAllowListEntry( WebSecurityPolicy::AddOriginAccessAllowListEntry(
extension.url(), WebString::FromUTF8(entry->protocol), extension.url(), WebString::FromUTF8(entry->protocol),
WebString::FromUTF8(entry->domain), entry->allow_subdomains, WebString::FromUTF8(entry->domain),
entry->mode ==
network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains,
entry->priority); entry->priority);
} }
for (const auto& entry : CreateCorsOriginAccessBlockList(extension)) { for (const auto& entry : CreateCorsOriginAccessBlockList(extension)) {
WebSecurityPolicy::AddOriginAccessBlockListEntry( WebSecurityPolicy::AddOriginAccessBlockListEntry(
extension.url(), WebString::FromUTF8(entry->protocol), extension.url(), WebString::FromUTF8(entry->protocol),
WebString::FromUTF8(entry->domain), entry->allow_subdomains, WebString::FromUTF8(entry->domain),
entry->mode ==
network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains,
entry->priority); entry->priority);
} }
} }
......
...@@ -76,7 +76,7 @@ class TestURLLoaderFactory : public mojom::URLLoaderFactory { ...@@ -76,7 +76,7 @@ class TestURLLoaderFactory : public mojom::URLLoaderFactory {
on_create_loader_and_start_ = closure; on_create_loader_and_start_ = closure;
} }
const network::ResourceRequest& request() const { return request_; } const ResourceRequest& request() const { return request_; }
const GURL& GetRequestedURL() const { return request_.url; } const GURL& GetRequestedURL() const { return request_.url; }
int num_created_loaders() const { return num_created_loaders_; } int num_created_loaders() const { return num_created_loaders_; }
...@@ -228,12 +228,10 @@ class CorsURLLoaderTest : public testing::Test { ...@@ -228,12 +228,10 @@ class CorsURLLoaderTest : public testing::Test {
void AddAllowListEntryForOrigin(const url::Origin& source_origin, void AddAllowListEntryForOrigin(const url::Origin& source_origin,
const std::string& protocol, const std::string& protocol,
const std::string& domain, const std::string& domain,
bool allow_subdomains) { const mojom::CorsOriginAccessMatchMode mode) {
origin_access_list_.AddAllowListEntryForOrigin( origin_access_list_.AddAllowListEntryForOrigin(
source_origin, source_origin, protocol, domain, mode,
network::mojom::CorsOriginPattern::New( mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
protocol, domain, allow_subdomains,
network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority));
} }
static net::RedirectInfo CreateRedirectInfo( static net::RedirectInfo CreateRedirectInfo(
...@@ -1014,8 +1012,9 @@ TEST_F(CorsURLLoaderTest, OriginAccessList) { ...@@ -1014,8 +1012,9 @@ TEST_F(CorsURLLoaderTest, OriginAccessList) {
// Adds an entry to allow the cross origin request beyond the CORS // Adds an entry to allow the cross origin request beyond the CORS
// rules. // rules.
AddAllowListEntryForOrigin(url::Origin::Create(origin), url.scheme(), AddAllowListEntryForOrigin(
url.host(), false); url::Origin::Create(origin), url.scheme(), url.host(),
mojom::CorsOriginAccessMatchMode::kDisallowSubdomains);
CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors); CreateLoaderAndStart(origin, url, mojom::FetchRequestMode::kCors);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
#include "url/origin.h" #include "url/origin.h"
#include "url/url_util.h" #include "url/url_util.h"
...@@ -125,6 +126,11 @@ OriginAccessEntry::MatchResult OriginAccessEntry::MatchesDomain( ...@@ -125,6 +126,11 @@ OriginAccessEntry::MatchResult OriginAccessEntry::MatchesDomain(
return kMatchesOrigin; return kMatchesOrigin;
} }
mojo::InlinedStructPtr<mojom::CorsOriginPattern>
OriginAccessEntry::CreateCorsOriginPattern() const {
return mojom::CorsOriginPattern::New(protocol_, host_, mode_, priority_);
}
} // namespace cors } // namespace cors
} // namespace network } // namespace network
...@@ -18,6 +18,10 @@ class Origin; ...@@ -18,6 +18,10 @@ class Origin;
namespace network { namespace network {
namespace mojom {
class CorsOriginPattern;
} // namespace mojom
namespace cors { namespace cors {
// A class to hold a protocol and host pair and to provide methods to determine // A class to hold a protocol and host pair and to provide methods to determine
...@@ -37,12 +41,11 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessEntry final { ...@@ -37,12 +41,11 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessEntry final {
// IPv6 addresses must include brackets (e.g. // IPv6 addresses must include brackets (e.g.
// '[2001:db8:85a3::8a2e:370:7334]', not '2001:db8:85a3::8a2e:370:7334'). // '[2001:db8:85a3::8a2e:370:7334]', not '2001:db8:85a3::8a2e:370:7334').
// The priority argument is used to break ties when multiple entries match. // The priority argument is used to break ties when multiple entries match.
OriginAccessEntry( OriginAccessEntry(const std::string& protocol,
const std::string& protocol,
const std::string& host, const std::string& host,
const mojom::CorsOriginAccessMatchMode mode, const mojom::CorsOriginAccessMatchMode mode,
const mojom::CorsOriginAccessMatchPriority priority = const mojom::CorsOriginAccessMatchPriority priority =
network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority); mojom::CorsOriginAccessMatchPriority::kDefaultPriority);
OriginAccessEntry(OriginAccessEntry&& from); OriginAccessEntry(OriginAccessEntry&& from);
// 'matchesOrigin' requires a protocol match (e.g. 'http' != 'https'). // 'matchesOrigin' requires a protocol match (e.g. 'http' != 'https').
...@@ -56,6 +59,11 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessEntry final { ...@@ -56,6 +59,11 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessEntry final {
return registerable_domain_; return registerable_domain_;
} }
// Creates mojom::CorsOriginPattern instance that represents |this|
// OriginAccessEntry instance.
mojo::InlinedStructPtr<mojom::CorsOriginPattern> CreateCorsOriginPattern()
const;
private: private:
const std::string protocol_; const std::string protocol_;
const std::string host_; const std::string host_;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "services/network/public/cpp/cors/origin_access_entry.h" #include "services/network/public/cpp/cors/origin_access_entry.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h" #include "url/gurl.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -315,6 +316,20 @@ TEST(OriginAccessEntryTest, IPAddressMatchingTest) { ...@@ -315,6 +316,20 @@ TEST(OriginAccessEntryTest, IPAddressMatchingTest) {
} }
} }
TEST(OriginAccessEntryTest, CreateCorsOriginPattern) {
const std::string kProtocol = "https";
const std::string kDomain = "google.com";
const auto kMode = mojom::CorsOriginAccessMatchMode::kAllowSubdomains;
const auto kPriority = mojom::CorsOriginAccessMatchPriority::kDefaultPriority;
OriginAccessEntry entry(kProtocol, kDomain, kMode, kPriority);
mojom::CorsOriginPatternPtr pattern = entry.CreateCorsOriginPattern();
DCHECK_EQ(kProtocol, pattern->protocol);
DCHECK_EQ(kDomain, pattern->domain);
DCHECK_EQ(kMode, pattern->mode);
DCHECK_EQ(kPriority, pattern->priority);
}
} // namespace } // namespace
} // namespace cors } // namespace cors
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "services/network/public/cpp/cors/origin_access_list.h" #include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
namespace network { namespace network {
namespace cors { namespace cors {
...@@ -13,14 +15,25 @@ OriginAccessList::~OriginAccessList() = default; ...@@ -13,14 +15,25 @@ OriginAccessList::~OriginAccessList() = default;
void OriginAccessList::SetAllowListForOrigin( void OriginAccessList::SetAllowListForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const std::vector<mojom::CorsOriginPatternPtr>& patterns) { const std::vector<CorsOriginPatternPtr>& patterns) {
SetForOrigin(source_origin, patterns, &allow_list_); SetForOrigin(source_origin, patterns, &allow_list_);
} }
void OriginAccessList::AddAllowListEntryForOrigin( void OriginAccessList::AddAllowListEntryForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const mojom::CorsOriginPatternPtr& pattern) { const std::string& protocol,
AddForOrigin(source_origin, pattern, &allow_list_); const std::string& domain,
const mojom::CorsOriginAccessMatchMode mode,
const mojom::CorsOriginAccessMatchPriority priority) {
AddForOrigin(source_origin,
mojom::CorsOriginPattern::New(protocol, domain, mode, priority),
&allow_list_);
}
void OriginAccessList::ClearAllowListForOrigin(
const url::Origin& source_origin) {
SetForOrigin(source_origin, std::vector<mojom::CorsOriginPatternPtr>(),
&allow_list_);
} }
void OriginAccessList::ClearAllowList() { void OriginAccessList::ClearAllowList() {
...@@ -29,14 +42,25 @@ void OriginAccessList::ClearAllowList() { ...@@ -29,14 +42,25 @@ void OriginAccessList::ClearAllowList() {
void OriginAccessList::SetBlockListForOrigin( void OriginAccessList::SetBlockListForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const std::vector<mojom::CorsOriginPatternPtr>& patterns) { const std::vector<CorsOriginPatternPtr>& patterns) {
SetForOrigin(source_origin, patterns, &block_list_); SetForOrigin(source_origin, patterns, &block_list_);
} }
void OriginAccessList::AddBlockListEntryForOrigin( void OriginAccessList::AddBlockListEntryForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const mojom::CorsOriginPatternPtr& pattern) { const std::string& protocol,
AddForOrigin(source_origin, pattern, &block_list_); const std::string& domain,
const mojom::CorsOriginAccessMatchMode mode,
const mojom::CorsOriginAccessMatchPriority priority) {
AddForOrigin(source_origin,
mojom::CorsOriginPattern::New(protocol, domain, mode, priority),
&block_list_);
}
void OriginAccessList::ClearBlockListForOrigin(
const url::Origin& source_origin) {
SetForOrigin(source_origin, std::vector<mojom::CorsOriginPatternPtr>(),
&block_list_);
} }
void OriginAccessList::ClearBlockList() { void OriginAccessList::ClearBlockList() {
...@@ -64,10 +88,38 @@ bool OriginAccessList::IsAllowed(const url::Origin& source_origin, ...@@ -64,10 +88,38 @@ bool OriginAccessList::IsAllowed(const url::Origin& source_origin,
return allow_list_priority > block_list_priority; return allow_list_priority > block_list_priority;
} }
std::vector<mojo::StructPtr<mojom::CorsOriginAccessPatterns>>
OriginAccessList::CreateCorsOriginAccessPatternsList() const {
std::set<std::string> origins;
for (const auto& allow_map : allow_list_)
origins.insert(allow_map.first);
for (const auto& block_map : block_list_)
origins.insert(block_map.first);
std::vector<mojom::CorsOriginAccessPatternsPtr> access_patterns;
for (const auto& origin : origins) {
std::vector<mojom::CorsOriginPatternPtr> allow_patterns;
const auto& allow_entries = allow_list_.find(origin);
if (allow_entries != allow_list_.end()) {
for (const auto& pattern : allow_entries->second)
allow_patterns.push_back(pattern.CreateCorsOriginPattern());
}
std::vector<mojom::CorsOriginPatternPtr> block_patterns;
const auto& block_entries = block_list_.find(origin);
if (block_entries != block_list_.end()) {
for (const auto& pattern : block_entries->second)
block_patterns.push_back(pattern.CreateCorsOriginPattern());
}
access_patterns.push_back(mojom::CorsOriginAccessPatterns::New(
origin, std::move(allow_patterns), std::move(block_patterns)));
}
return access_patterns;
}
// static // static
void OriginAccessList::SetForOrigin( void OriginAccessList::SetForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const std::vector<mojom::CorsOriginPatternPtr>& patterns, const std::vector<CorsOriginPatternPtr>& patterns,
PatternMap* map) { PatternMap* map) {
DCHECK(map); DCHECK(map);
DCHECK(!source_origin.opaque()); DCHECK(!source_origin.opaque());
...@@ -80,28 +132,20 @@ void OriginAccessList::SetForOrigin( ...@@ -80,28 +132,20 @@ void OriginAccessList::SetForOrigin(
Patterns& native_patterns = (*map)[source]; Patterns& native_patterns = (*map)[source];
for (const auto& pattern : patterns) { for (const auto& pattern : patterns) {
native_patterns.push_back(OriginAccessEntry( native_patterns.push_back(OriginAccessEntry(
pattern->protocol, pattern->domain, pattern->protocol, pattern->domain, pattern->mode, pattern->priority));
pattern->allow_subdomains
? mojom::CorsOriginAccessMatchMode::kAllowSubdomains
: mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
pattern->priority));
} }
} }
// static // static
void OriginAccessList::AddForOrigin(const url::Origin& source_origin, void OriginAccessList::AddForOrigin(const url::Origin& source_origin,
const mojom::CorsOriginPatternPtr& pattern, const CorsOriginPatternPtr& pattern,
PatternMap* map) { PatternMap* map) {
DCHECK(map); DCHECK(map);
DCHECK(!source_origin.opaque()); DCHECK(!source_origin.opaque());
std::string source = source_origin.Serialize(); std::string source = source_origin.Serialize();
(*map)[source].push_back(OriginAccessEntry( (*map)[source].push_back(OriginAccessEntry(pattern->protocol, pattern->domain,
pattern->protocol, pattern->domain, pattern->mode, pattern->priority));
pattern->allow_subdomains
? mojom::CorsOriginAccessMatchMode::kAllowSubdomains
: mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
pattern->priority));
} }
// static // static
......
...@@ -12,30 +12,44 @@ ...@@ -12,30 +12,44 @@
#include "base/component_export.h" #include "base/component_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "services/network/public/cpp/cors/origin_access_entry.h" #include "services/network/public/cpp/cors/origin_access_entry.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom.h" #include "services/network/public/mojom/cors_origin_pattern.mojom-shared.h"
#include "url/origin.h" #include "url/origin.h"
namespace network { namespace network {
namespace mojom {
class CorsOriginPattern;
class CorsOriginAccessPatterns;
} // namespace mojom
namespace cors { namespace cors {
// A class to manage origin access allow / block lists. If these lists conflict, // A class to manage origin access allow / block lists. If these lists conflict,
// blacklisting is respected. These lists are managed per source-origin basis. // blacklisting is respected. These lists are managed per source-origin basis.
class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList { class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList {
public: public:
using CorsOriginPatternPtr = mojo::InlinedStructPtr<mojom::CorsOriginPattern>;
OriginAccessList(); OriginAccessList();
~OriginAccessList(); ~OriginAccessList();
// Clears the old allow list for |source_origin|, and set |patterns| to the // Clears the old allow list for |source_origin|, and set |patterns| to the
// allow list. When two or more patterns in a list match, the entry with the // allow list. When two or more patterns in a list match, the entry with the
// higher |priority| takes precedence. // higher |priority| takes precedence.
void SetAllowListForOrigin( void SetAllowListForOrigin(const url::Origin& source_origin,
const std::vector<CorsOriginPatternPtr>& patterns);
// Adds an access pattern by |protocol|, |domain|, |mode|, and |priority|,
// to the allow list for |source_origin|.
void AddAllowListEntryForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const std::vector<mojom::CorsOriginPatternPtr>& patterns); const std::string& protocol,
const std::string& domain,
const mojom::CorsOriginAccessMatchMode mode,
const mojom::CorsOriginAccessMatchPriority priority);
// Adds |pattern| to the allow list for |source_origin|. // Clears the old allow list for |source_origin|.
void AddAllowListEntryForOrigin(const url::Origin& source_origin, void ClearAllowListForOrigin(const url::Origin& source_origin);
const mojom::CorsOriginPatternPtr& pattern);
// Clears the old allow list. // Clears the old allow list.
void ClearAllowList(); void ClearAllowList();
...@@ -43,13 +57,20 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList { ...@@ -43,13 +57,20 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList {
// Clears the old block list for |source_origin| and set |patterns| to the // Clears the old block list for |source_origin| and set |patterns| to the
// block list. When two or more patterns in a list match, the entry with the // block list. When two or more patterns in a list match, the entry with the
// higher |priority| takes precedence. // higher |priority| takes precedence.
void SetBlockListForOrigin( void SetBlockListForOrigin(const url::Origin& source_origin,
const std::vector<CorsOriginPatternPtr>& patterns);
// Adds an access pattern by |protocol|, |domain|, |mode|, and |priority|,
// to the block list for |source_origin|.
void AddBlockListEntryForOrigin(
const url::Origin& source_origin, const url::Origin& source_origin,
const std::vector<mojom::CorsOriginPatternPtr>& patterns); const std::string& protocol,
const std::string& domain,
const mojom::CorsOriginAccessMatchMode mode,
const mojom::CorsOriginAccessMatchPriority priority);
// Adds |pattern| to the block list for |source_origin|. // Clears the old block list for |source_origin|.
void AddBlockListEntryForOrigin(const url::Origin& source_origin, void ClearBlockListForOrigin(const url::Origin& source_origin);
const mojom::CorsOriginPatternPtr& pattern);
// Clears the old block list. // Clears the old block list.
void ClearBlockList(); void ClearBlockList();
...@@ -59,22 +80,28 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList { ...@@ -59,22 +80,28 @@ class COMPONENT_EXPORT(NETWORK_CPP) OriginAccessList {
bool IsAllowed(const url::Origin& source_origin, bool IsAllowed(const url::Origin& source_origin,
const GURL& destination) const; const GURL& destination) const;
// Creates mojom::CorsPriginAccessPatterns instance vector that represents
// |this| OriginAccessList instance.
std::vector<mojo::StructPtr<mojom::CorsOriginAccessPatterns>>
CreateCorsOriginAccessPatternsList() const;
private: private:
using Patterns = std::vector<OriginAccessEntry>; using Patterns = std::vector<OriginAccessEntry>;
using PatternMap = std::map<std::string, Patterns>; using PatternMap = std::map<std::string, Patterns>;
static void SetForOrigin( static void SetForOrigin(const url::Origin& source_origin,
const url::Origin& source_origin, const std::vector<CorsOriginPatternPtr>& patterns,
const std::vector<mojom::CorsOriginPatternPtr>& patterns,
PatternMap* map); PatternMap* map);
static void AddForOrigin(const url::Origin& source_origin, static void AddForOrigin(const url::Origin& source_origin,
const mojom::CorsOriginPatternPtr& pattern, const CorsOriginPatternPtr& pattern,
PatternMap* map); PatternMap* map);
static network::mojom::CorsOriginAccessMatchPriority static mojom::CorsOriginAccessMatchPriority GetHighestPriorityOfRuleForOrigin(
GetHighestPriorityOfRuleForOrigin(const std::string& source, const std::string& source,
const url::Origin& destination_origin, const url::Origin& destination_origin,
const PatternMap& map); const PatternMap& map);
// TODO(toyoshim): Redesign to have an unified map to be consistent with
// mojom::CorsOriginAccessPatterns. See https://crbug.com/908756.
PatternMap allow_list_; PatternMap allow_list_;
PatternMap block_list_; PatternMap block_list_;
......
...@@ -27,7 +27,7 @@ enum CorsOriginAccessMatchPriority { ...@@ -27,7 +27,7 @@ enum CorsOriginAccessMatchPriority {
kMaxPriority kMaxPriority
}; };
// Parameters for representing a access origin whitelist or blacklist for CORS. // Parameters for representing a access origin allowlist or blocklist for CORS.
struct CorsOriginPattern { struct CorsOriginPattern {
// The protocol part of the destination URL. // The protocol part of the destination URL.
string protocol; string protocol;
...@@ -35,8 +35,8 @@ struct CorsOriginPattern { ...@@ -35,8 +35,8 @@ struct CorsOriginPattern {
// The domain part of the destination URL. // The domain part of the destination URL.
string domain; string domain;
// Whether subdomains match this protocol and host pattern. // Specifies a mode for domain match.
bool allow_subdomains; CorsOriginAccessMatchMode mode;
// Order of preference in which the pattern is applied. Higher priority // Order of preference in which the pattern is applied. Higher priority
// patterns take precedence over lower ones. In the case were both a // patterns take precedence over lower ones. In the case were both a
...@@ -44,3 +44,12 @@ struct CorsOriginPattern { ...@@ -44,3 +44,12 @@ struct CorsOriginPattern {
// the block list rule takes priority. // the block list rule takes priority.
CorsOriginAccessMatchPriority priority; CorsOriginAccessMatchPriority priority;
}; };
// Parameters for representing pairs of source origin and allow/block-lists
// for CORS.
struct CorsOriginAccessPatterns {
string source_origin;
array<CorsOriginPattern> allow_patterns;
array<CorsOriginPattern> block_patterns;
};
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include "base/strings/pattern.h" #include "base/strings/pattern.h"
#include "services/network/public/cpp/cors/origin_access_list.h" #include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom-shared.h"
#include "services/network/public/mojom/referrer_policy.mojom-blink.h" #include "services/network/public/mojom/referrer_policy.mojom-blink.h"
#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
...@@ -247,10 +246,12 @@ void SecurityPolicy::AddOriginAccessAllowListEntry( ...@@ -247,10 +246,12 @@ void SecurityPolicy::AddOriginAccessAllowListEntry(
const network::mojom::CorsOriginAccessMatchPriority priority) { const network::mojom::CorsOriginAccessMatchPriority priority) {
MutexLocker lock(GetMutex()); MutexLocker lock(GetMutex());
GetOriginAccessList().AddAllowListEntryForOrigin( GetOriginAccessList().AddAllowListEntryForOrigin(
source_origin.ToUrlOrigin(), network::mojom::CorsOriginPattern::New( source_origin.ToUrlOrigin(), WebString(destination_protocol).Utf8(),
WebString(destination_protocol).Utf8(),
WebString(destination_domain).Utf8(), WebString(destination_domain).Utf8(),
allow_destination_subdomains, priority)); allow_destination_subdomains
? network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains
: network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
priority);
} }
void SecurityPolicy::AddOriginAccessBlockListEntry( void SecurityPolicy::AddOriginAccessBlockListEntry(
...@@ -261,21 +262,20 @@ void SecurityPolicy::AddOriginAccessBlockListEntry( ...@@ -261,21 +262,20 @@ void SecurityPolicy::AddOriginAccessBlockListEntry(
const network::mojom::CorsOriginAccessMatchPriority priority) { const network::mojom::CorsOriginAccessMatchPriority priority) {
MutexLocker lock(GetMutex()); MutexLocker lock(GetMutex());
GetOriginAccessList().AddBlockListEntryForOrigin( GetOriginAccessList().AddBlockListEntryForOrigin(
source_origin.ToUrlOrigin(), network::mojom::CorsOriginPattern::New( source_origin.ToUrlOrigin(), WebString(destination_protocol).Utf8(),
WebString(destination_protocol).Utf8(),
WebString(destination_domain).Utf8(), WebString(destination_domain).Utf8(),
allow_destination_subdomains, priority)); allow_destination_subdomains
? network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains
: network::mojom::CorsOriginAccessMatchMode::kDisallowSubdomains,
priority);
} }
void SecurityPolicy::ClearOriginAccessListForOrigin( void SecurityPolicy::ClearOriginAccessListForOrigin(
const SecurityOrigin& source_origin) { const SecurityOrigin& source_origin) {
MutexLocker lock(GetMutex()); MutexLocker lock(GetMutex());
GetOriginAccessList().SetAllowListForOrigin( const url::Origin origin = source_origin.ToUrlOrigin();
source_origin.ToUrlOrigin(), GetOriginAccessList().ClearAllowListForOrigin(origin);
std::vector<network::mojom::CorsOriginPatternPtr>()); GetOriginAccessList().ClearBlockListForOrigin(origin);
GetOriginAccessList().SetBlockListForOrigin(
source_origin.ToUrlOrigin(),
std::vector<network::mojom::CorsOriginPatternPtr>());
} }
void SecurityPolicy::ClearOriginAccessList() { void SecurityPolicy::ClearOriginAccessList() {
......
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