Skip to content

Commit

Permalink
Origin policy: add parsing for "ids" member
Browse files Browse the repository at this point in the history
This parses the "ids" member according to the spec at
https://wicg.github.io/origin-policy/#parse-a-string-into-an-origin-policy,
and stores the result in the OriginPolicyContents structure.

The results are not yet used by any part of the system, and as such this
is not yet web exposed. That will be done in a follow-on patch, which
exposes them as self.originPolicyIds after plumbing them through Blink.

Bug: 1057123
Change-Id: I66637945486b5bd554605094a0e26b62c44558de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2087986
Reviewed-by: Charlie Reis <creis@chromium.org>
Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org>
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747594}
  • Loading branch information
domenic authored and Commit Bot committed Mar 6, 2020
1 parent de3f09f commit 6b0034c
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 73 deletions.
16 changes: 8 additions & 8 deletions content/browser/isolated_origin_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class OriginIsolationOptInTest : public IsolatedOriginTestBase {
// In this test the sub-origin is isolated because the origin policy requests
// "isolation". It will have a different site instance than the main frame.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, SimpleSubOriginIsolationTest) {
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
// Start off with an a(a) page, then navigate the subframe to an isolated sub
// origin.
GURL test_url(https_server()->GetURL("foo.com",
Expand Down Expand Up @@ -224,7 +224,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, SimpleSubOriginIsolationTest) {
// request "isolation". It will have the same site instance as the main frame.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
SimpleSubOriginNonIsolationTest) {
SetOriginPolicyManifest(R"({ })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"] })");
// Start off with an a(a) page, then navigate the subframe to an isolated sub
// origin.
GURL test_url(https_server()->GetURL("foo.com",
Expand All @@ -245,7 +245,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
// This test verifies that renderer-initiated navigations to/from isolated
// sub-origins works as expected.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, RendererInitiatedNavigations) {
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
GURL test_url(https_server()->GetURL("foo.com",
"/cross_site_iframe_factory.html?"
"foo.com(foo.com)"));
Expand Down Expand Up @@ -287,7 +287,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, RendererInitiatedNavigations) {
// Note: this test is essentially identical to
// IsolatedOriginTest.MainFrameNavigation.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, MainFrameNavigation) {
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
GURL unisolated_url(https_server()->GetURL("www.foo.com", "/title1.html"));
GURL isolated_url(https_server()->GetURL("isolated.foo.com", "/isolate_me"));

Expand Down Expand Up @@ -361,7 +361,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, MainFrameNavigation) {
// if a new policy is received that removes the opt-in request.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
OriginIsolationStateRetainedForBrowsingInstance) {
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
// Start off with an a(a,a) page, then navigate the subframe to an isolated
// sub origin.
GURL test_url(https_server()->GetURL("foo.com",
Expand Down Expand Up @@ -406,7 +406,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
IN_PROC_BROWSER_TEST_F(
OriginIsolationOptInTest,
DISABLED_OriginNonIsolationStateRetainedForBrowsingInstance) {
SetOriginPolicyManifest(R"({ })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"] })");
// Start off with an a(a,a) page, then navigate the subframe to an isolated
// sub origin.
GURL test_url(https_server()->GetURL("foo.com",
Expand All @@ -427,7 +427,7 @@ IN_PROC_BROWSER_TEST_F(

// Change OriginPolicy manifest to start isolating the sub-origin. It should
// still be isolated, to remain consistent with the other frame.
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
NavigateFrameToURL(child_frame_node1, isolated_sub_origin);
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child_frame_node1->current_frame_host()->GetSiteInstance());
Expand All @@ -446,7 +446,7 @@ IN_PROC_BROWSER_TEST_F(
// site-keyed SiteInstance corresponding to the base-origin, and not the
// origin-keyed SiteInstance the base origin is assigned to.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, IsolatedBaseOrigin) {
SetOriginPolicyManifest(R"({ "isolation": true })");
SetOriginPolicyManifest(R"({ "ids": ["my-policy"], "isolation": true })");
// Start off with an isolated base-origin in an a(a) configuration, then
// navigate the subframe to a sub-origin no requesting isolation.
GURL test_url(https_server()->GetURL(
Expand Down
28 changes: 28 additions & 0 deletions services/network/origin_policy/origin_policy_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ void OriginPolicyParser::DoParse(base::StringPiece policy_contents_text) {
if (!json || !json->is_dict())
return;

if (!ParseIds(*json)) {
return;
}

if (base::Value* content_security = json->FindDictKey("content_security")) {
ParseContentSecurity(*content_security);
}
Expand All @@ -52,6 +56,23 @@ void OriginPolicyParser::DoParse(base::StringPiece policy_contents_text) {
}
}

bool OriginPolicyParser::ParseIds(const base::Value& json) {
const base::Value* raw_ids = json.FindListKey("ids");
if (!raw_ids) {
return false;
}
for (const auto& id : raw_ids->GetList()) {
if (id.is_string()) {
const std::string& id_string = id.GetString();
if (IsValidOriginPolicyId(id_string)) {
policy_contents_->ids.push_back(id_string);
}
}
}

return !policy_contents_->ids.empty();
}

void OriginPolicyParser::ParseContentSecurity(
const base::Value& content_security) {
const base::Value* policies = content_security.FindListKey("policies");
Expand Down Expand Up @@ -103,4 +124,11 @@ void OriginPolicyParser::ParseIsolation(const base::Value& policy) {
policy_contents_->isolation_optin_hints = hints;
}

// https://wicg.github.io/origin-policy/#valid-origin-policy-id
bool OriginPolicyParser::IsValidOriginPolicyId(const std::string& id) {
return !id.empty() && std::none_of(id.begin(), id.end(), [](char ch) {
return ch < 0x20 || ch > 0x7E;
});
}

} // namespace network
7 changes: 7 additions & 0 deletions services/network/origin_policy/origin_policy_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) OriginPolicyParser {

void DoParse(base::StringPiece);

// Only parsing IDs can cause a parsing failure (i.e. returning the empty
// policy from Parse()), so only it gets a bool return value. Failures parsing
// the others will just result in not filling out their piece of
// policy_contents_.
bool ParseIds(const base::Value&);
void ParseContentSecurity(const base::Value&);
void ParseFeatures(const base::Value&);
void ParseIsolation(const base::Value&);

static bool IsValidOriginPolicyId(const std::string&);

OriginPolicyContentsPtr policy_contents_;

DISALLOW_COPY_AND_ASSIGN(OriginPolicyParser);
Expand Down
Loading

0 comments on commit 6b0034c

Please sign in to comment.