Commit 869ce20f authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

Unit tests for handling |isolated_world_origin| in CorsURLLoader.

Bug: 940068
Change-Id: Ibf46c4aacf8aa29d4b1ca96aab6d40309f3f5b8a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1788462Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695666}
parent 78cd9352
......@@ -1220,6 +1220,92 @@ TEST_F(CorsURLLoaderTest, OriginAccessList_Allowed) {
EXPECT_EQ(net::OK, client().completion_status().error_code);
}
// Tests if CorsURLLoader takes into account
// ResourceRequest::isolated_world_origin when consulting OriginAccessList.
TEST_F(CorsURLLoaderTest, OriginAccessList_IsolatedWorldOrigin) {
const GURL main_world_origin("http://main-world.com");
const GURL isolated_world_origin("http://isolated-world.com");
const GURL url("http://other.com/foo.png");
AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin),
url.scheme(), url.host(),
mojom::CorsDomainMatchMode::kDisallowSubdomains);
ResourceRequest request;
request.mode = mojom::RequestMode::kCors;
request.credentials_mode = mojom::CredentialsMode::kOmit;
request.method = net::HttpRequestHeaders::kGetMethod;
request.url = url;
request.request_initiator = url::Origin::Create(main_world_origin);
request.isolated_world_origin = url::Origin::Create(isolated_world_origin);
CreateLoaderAndStart(request);
NotifyLoaderClientOnReceiveResponse();
NotifyLoaderClientOnComplete(net::OK);
RunUntilComplete();
EXPECT_TRUE(IsNetworkLoaderStarted());
EXPECT_FALSE(client().has_received_redirect());
EXPECT_TRUE(client().has_received_response());
EXPECT_EQ(network::mojom::FetchResponseType::kBasic,
client().response_head().response_type);
EXPECT_TRUE(client().has_received_completion());
EXPECT_EQ(net::OK, client().completion_status().error_code);
}
// Tests if CorsURLLoader takes into account
// ResourceRequest::isolated_world_origin when consulting OriginAccessList
// after redirects.
TEST_F(CorsURLLoaderTest, OriginAccessList_IsolatedWorldOrigin_Redirect) {
const GURL main_world_origin("http://main-world.com");
const GURL isolated_world_origin("http://isolated-world.com");
const GURL url("http://other.com/foo.png");
// |new_url| is same-origin as |url| to avoid tainting the response
// in CorsURLLoader::OnReceiveRedirect.
const GURL new_url("http://other.com/bar.png");
AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin),
url.scheme(), url.host(),
mojom::CorsDomainMatchMode::kDisallowSubdomains);
AddAllowListEntryForOrigin(url::Origin::Create(isolated_world_origin),
new_url.scheme(), new_url.host(),
mojom::CorsDomainMatchMode::kDisallowSubdomains);
ResourceRequest request;
// Using no-cors to force opaque response (unless the allowlist entry added
// above is taken into account).
request.mode = mojom::RequestMode::kNoCors;
request.credentials_mode = mojom::CredentialsMode::kOmit;
request.method = net::HttpRequestHeaders::kGetMethod;
request.url = url;
request.request_initiator = url::Origin::Create(main_world_origin);
request.isolated_world_origin = url::Origin::Create(isolated_world_origin);
CreateLoaderAndStart(request);
NotifyLoaderClientOnReceiveRedirect(CreateRedirectInfo(301, "GET", new_url));
RunUntilRedirectReceived();
EXPECT_TRUE(IsNetworkLoaderStarted());
EXPECT_FALSE(client().has_received_completion());
EXPECT_FALSE(client().has_received_response());
EXPECT_TRUE(client().has_received_redirect());
FollowRedirect();
NotifyLoaderClientOnReceiveResponse();
NotifyLoaderClientOnComplete(net::OK);
RunUntilComplete();
EXPECT_TRUE(IsNetworkLoaderStarted());
EXPECT_TRUE(client().has_received_redirect());
EXPECT_TRUE(client().has_received_response());
EXPECT_EQ(network::mojom::FetchResponseType::kBasic,
client().response_head().response_type);
EXPECT_TRUE(client().has_received_completion());
EXPECT_EQ(net::OK, client().completion_status().error_code);
}
// Check if higher-priority block list wins.
TEST_F(CorsURLLoaderTest, OriginAccessList_Blocked) {
const GURL origin("http://example.com");
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/cors.mojom.h"
#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
......@@ -59,6 +60,17 @@ class OriginAccessListTest : public testing::Test {
const url::Origin& https_google_origin() const {
return https_google_origin_;
}
const url::Origin& source_origin() const { return source_origin_; }
OriginAccessList::AccessState CheckAccess(
const url::Origin& request_initiator,
const base::Optional<url::Origin>& isolated_world_origin,
const GURL& url) {
ResourceRequest request;
request.url = url;
request.request_initiator = request_initiator;
request.isolated_world_origin = isolated_world_origin;
return list_.CheckAccessState(request);
}
bool IsAllowed(const url::Origin& destination_origin) const {
return list_.CheckAccessState(source_origin_,
destination_origin.GetURL()) ==
......@@ -140,6 +152,38 @@ TEST_F(OriginAccessListTest, IsAccessAllowedWithPort) {
EXPECT_TRUE(IsAllowed(https_another_port_example_origin()));
}
TEST_F(OriginAccessListTest, IsAccessAllowedForIsolatedWorldOrigin) {
// By default, no access should be allowed.
EXPECT_FALSE(IsAllowed(https_example_origin()));
// Adding access for https://example.com should work, but should not grant
// access to different ports for the same scheme:host pair.
GURL target("https://example.com");
SetAllowListEntry(target.scheme(), target.host(), kHttpsPort,
kDisallowSubdomains, kAllowOnlySpecifiedPort);
// When request is made by a Chrome Extension background page,
// request_initiator is the origin that should be used as a key for
// OriginAccessList.
EXPECT_EQ(OriginAccessList::AccessState::kAllowed,
CheckAccess(source_origin(), base::nullopt, target));
// When request is made by a Chrome Extension content script,
// isolated_world_origin is the origin that should be used as a key for
// OriginAccessList.
EXPECT_EQ(OriginAccessList::AccessState::kAllowed,
CheckAccess(https_another_port_example_origin(), source_origin(),
target));
// Impossible situation with Chrome Extensions - the isolated_world_origin is
// non-empty, but request_intiator is the key in the OriginAccessList. In
// this impossible situation it is okay to indicate that no entry is listed
// in the OriginAccessList.
EXPECT_EQ(OriginAccessList::AccessState::kNotListed,
CheckAccess(source_origin(), https_another_port_example_origin(),
target));
}
TEST_F(OriginAccessListTest, IsAccessAllowed) {
// By default, no access should be allowed.
EXPECT_FALSE(IsAllowed(https_example_origin()));
......
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