Commit 6b0034c8 authored by Domenic Denicola's avatar Domenic Denicola Committed by Commit Bot

Origin policy: add parsing for "ids" member

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/+/2087986Reviewed-by: default avatarCharlie Reis <creis@chromium.org>
Reviewed-by: default avatarDaniel Vogelheim <vogelheim@chromium.org>
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747594}
parent de3f09f8
...@@ -191,7 +191,7 @@ class OriginIsolationOptInTest : public IsolatedOriginTestBase { ...@@ -191,7 +191,7 @@ class OriginIsolationOptInTest : public IsolatedOriginTestBase {
// In this test the sub-origin is isolated because the origin policy requests // 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. // "isolation". It will have a different site instance than the main frame.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, SimpleSubOriginIsolationTest) { 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 // Start off with an a(a) page, then navigate the subframe to an isolated sub
// origin. // origin.
GURL test_url(https_server()->GetURL("foo.com", GURL test_url(https_server()->GetURL("foo.com",
...@@ -224,7 +224,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, SimpleSubOriginIsolationTest) { ...@@ -224,7 +224,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, SimpleSubOriginIsolationTest) {
// request "isolation". It will have the same site instance as the main frame. // request "isolation". It will have the same site instance as the main frame.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
SimpleSubOriginNonIsolationTest) { SimpleSubOriginNonIsolationTest) {
SetOriginPolicyManifest(R"({ })"); SetOriginPolicyManifest(R"({ "ids": ["my-policy"] })");
// Start off with an a(a) page, then navigate the subframe to an isolated sub // Start off with an a(a) page, then navigate the subframe to an isolated sub
// origin. // origin.
GURL test_url(https_server()->GetURL("foo.com", GURL test_url(https_server()->GetURL("foo.com",
...@@ -245,7 +245,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, ...@@ -245,7 +245,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
// This test verifies that renderer-initiated navigations to/from isolated // This test verifies that renderer-initiated navigations to/from isolated
// sub-origins works as expected. // sub-origins works as expected.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, RendererInitiatedNavigations) { 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", GURL test_url(https_server()->GetURL("foo.com",
"/cross_site_iframe_factory.html?" "/cross_site_iframe_factory.html?"
"foo.com(foo.com)")); "foo.com(foo.com)"));
...@@ -287,7 +287,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, RendererInitiatedNavigations) { ...@@ -287,7 +287,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, RendererInitiatedNavigations) {
// Note: this test is essentially identical to // Note: this test is essentially identical to
// IsolatedOriginTest.MainFrameNavigation. // IsolatedOriginTest.MainFrameNavigation.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, 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 unisolated_url(https_server()->GetURL("www.foo.com", "/title1.html"));
GURL isolated_url(https_server()->GetURL("isolated.foo.com", "/isolate_me")); GURL isolated_url(https_server()->GetURL("isolated.foo.com", "/isolate_me"));
...@@ -361,7 +361,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, MainFrameNavigation) { ...@@ -361,7 +361,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, MainFrameNavigation) {
// if a new policy is received that removes the opt-in request. // if a new policy is received that removes the opt-in request.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
OriginIsolationStateRetainedForBrowsingInstance) { 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 // Start off with an a(a,a) page, then navigate the subframe to an isolated
// sub origin. // sub origin.
GURL test_url(https_server()->GetURL("foo.com", GURL test_url(https_server()->GetURL("foo.com",
...@@ -406,7 +406,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, ...@@ -406,7 +406,7 @@ IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest,
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
OriginIsolationOptInTest, OriginIsolationOptInTest,
DISABLED_OriginNonIsolationStateRetainedForBrowsingInstance) { DISABLED_OriginNonIsolationStateRetainedForBrowsingInstance) {
SetOriginPolicyManifest(R"({ })"); SetOriginPolicyManifest(R"({ "ids": ["my-policy"] })");
// Start off with an a(a,a) page, then navigate the subframe to an isolated // Start off with an a(a,a) page, then navigate the subframe to an isolated
// sub origin. // sub origin.
GURL test_url(https_server()->GetURL("foo.com", GURL test_url(https_server()->GetURL("foo.com",
...@@ -427,7 +427,7 @@ IN_PROC_BROWSER_TEST_F( ...@@ -427,7 +427,7 @@ IN_PROC_BROWSER_TEST_F(
// Change OriginPolicy manifest to start isolating the sub-origin. It should // Change OriginPolicy manifest to start isolating the sub-origin. It should
// still be isolated, to remain consistent with the other frame. // 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); NavigateFrameToURL(child_frame_node1, isolated_sub_origin);
EXPECT_EQ(root->current_frame_host()->GetSiteInstance(), EXPECT_EQ(root->current_frame_host()->GetSiteInstance(),
child_frame_node1->current_frame_host()->GetSiteInstance()); child_frame_node1->current_frame_host()->GetSiteInstance());
...@@ -446,7 +446,7 @@ IN_PROC_BROWSER_TEST_F( ...@@ -446,7 +446,7 @@ IN_PROC_BROWSER_TEST_F(
// site-keyed SiteInstance corresponding to the base-origin, and not the // site-keyed SiteInstance corresponding to the base-origin, and not the
// origin-keyed SiteInstance the base origin is assigned to. // origin-keyed SiteInstance the base origin is assigned to.
IN_PROC_BROWSER_TEST_F(OriginIsolationOptInTest, IsolatedBaseOrigin) { 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 // Start off with an isolated base-origin in an a(a) configuration, then
// navigate the subframe to a sub-origin no requesting isolation. // navigate the subframe to a sub-origin no requesting isolation.
GURL test_url(https_server()->GetURL( GURL test_url(https_server()->GetURL(
......
...@@ -35,6 +35,10 @@ void OriginPolicyParser::DoParse(base::StringPiece policy_contents_text) { ...@@ -35,6 +35,10 @@ void OriginPolicyParser::DoParse(base::StringPiece policy_contents_text) {
if (!json || !json->is_dict()) if (!json || !json->is_dict())
return; return;
if (!ParseIds(*json)) {
return;
}
if (base::Value* content_security = json->FindDictKey("content_security")) { if (base::Value* content_security = json->FindDictKey("content_security")) {
ParseContentSecurity(*content_security); ParseContentSecurity(*content_security);
} }
...@@ -52,6 +56,23 @@ void OriginPolicyParser::DoParse(base::StringPiece policy_contents_text) { ...@@ -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( void OriginPolicyParser::ParseContentSecurity(
const base::Value& content_security) { const base::Value& content_security) {
const base::Value* policies = content_security.FindListKey("policies"); const base::Value* policies = content_security.FindListKey("policies");
...@@ -103,4 +124,11 @@ void OriginPolicyParser::ParseIsolation(const base::Value& policy) { ...@@ -103,4 +124,11 @@ void OriginPolicyParser::ParseIsolation(const base::Value& policy) {
policy_contents_->isolation_optin_hints = hints; 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 } // namespace network
...@@ -31,10 +31,17 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) OriginPolicyParser { ...@@ -31,10 +31,17 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) OriginPolicyParser {
void DoParse(base::StringPiece); 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 ParseContentSecurity(const base::Value&);
void ParseFeatures(const base::Value&); void ParseFeatures(const base::Value&);
void ParseIsolation(const base::Value&); void ParseIsolation(const base::Value&);
static bool IsValidOriginPolicyId(const std::string&);
OriginPolicyContentsPtr policy_contents_; OriginPolicyContentsPtr policy_contents_;
DISALLOW_COPY_AND_ASSIGN(OriginPolicyParser); DISALLOW_COPY_AND_ASSIGN(OriginPolicyParser);
......
...@@ -23,11 +23,13 @@ OriginPolicyContents::OriginPolicyContents(const OriginPolicyContents& other) = ...@@ -23,11 +23,13 @@ OriginPolicyContents::OriginPolicyContents(const OriginPolicyContents& other) =
default; default;
OriginPolicyContents::OriginPolicyContents( OriginPolicyContents::OriginPolicyContents(
const std::vector<std::string>& ids,
const base::Optional<std::string>& feature_policy, const base::Optional<std::string>& feature_policy,
const std::vector<std::string>& content_security_policies, const std::vector<std::string>& content_security_policies,
const std::vector<std::string>& content_security_policies_report_only, const std::vector<std::string>& content_security_policies_report_only,
const base::Optional<IsolationOptInHints>& isolation_optin_hints) const base::Optional<IsolationOptInHints>& isolation_optin_hints)
: feature_policy(feature_policy), : ids(ids),
feature_policy(feature_policy),
content_security_policies(content_security_policies), content_security_policies(content_security_policies),
content_security_policies_report_only( content_security_policies_report_only(
content_security_policies_report_only), content_security_policies_report_only),
...@@ -37,7 +39,7 @@ OriginPolicyContents& OriginPolicyContents::operator=( ...@@ -37,7 +39,7 @@ OriginPolicyContents& OriginPolicyContents::operator=(
const OriginPolicyContents& other) = default; const OriginPolicyContents& other) = default;
bool OriginPolicyContents::operator==(const OriginPolicyContents& other) const { bool OriginPolicyContents::operator==(const OriginPolicyContents& other) const {
return feature_policy == other.feature_policy && return ids == other.ids && feature_policy == other.feature_policy &&
content_security_policies == other.content_security_policies && content_security_policies == other.content_security_policies &&
content_security_policies_report_only == content_security_policies_report_only ==
other.content_security_policies_report_only && other.content_security_policies_report_only &&
......
...@@ -45,6 +45,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) OriginPolicyContents { ...@@ -45,6 +45,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) OriginPolicyContents {
OriginPolicyContents(); OriginPolicyContents();
~OriginPolicyContents(); ~OriginPolicyContents();
OriginPolicyContents( OriginPolicyContents(
const std::vector<std::string>& ids,
const base::Optional<std::string>& feature_policy, const base::Optional<std::string>& feature_policy,
const std::vector<std::string>& content_security_policies, const std::vector<std::string>& content_security_policies,
const std::vector<std::string>& content_security_policies_report_only, const std::vector<std::string>& content_security_policies_report_only,
...@@ -56,6 +57,18 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) OriginPolicyContents { ...@@ -56,6 +57,18 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) OriginPolicyContents {
OriginPolicyContentsPtr ClonePtr(); OriginPolicyContentsPtr ClonePtr();
// The origin policy's IDs, which are compared with the requested ID values
// from the Origin-Policy HTTP header to determine whether this origin policy
// can apply or not. For more information see:
// - https://wicg.github.io/origin-policy/#origin-policy-ids
// - https://wicg.github.io/origin-policy/#manifest-ids
// - https://github.com/WICG/origin-policy/blob/master/version-negotiation.md
// - https://wicg.github.io/origin-policy/#examples
//
// By the time it is stored in this structure, the vector is guaranteed to be
// non-empty and to contain only valid origin policy IDs.
std::vector<std::string> ids;
// The feature policy that is dictated by the origin policy, if any. // The feature policy that is dictated by the origin policy, if any.
// https://w3c.github.io/webappsec-feature-policy/ // https://w3c.github.io/webappsec-feature-policy/
// This is stored as a raw string, so it is not guaranteed to be an actual // This is stored as a raw string, so it is not guaranteed to be an actual
......
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