Skip to content

Commit

Permalink
[Permissions Policy Wildcards] (4) Parse wildcard subdomain matches
Browse files Browse the repository at this point in the history
This CL finally implements the critical `origin with subdomain wildcard
parser` portion of the code! It's not a lot of code, but needs some deep
testing to be sure we aren't opening ourselves up to trouble. WPTs are
split into the next CL so that we don't distract from targeted review
here.
Design doc:
w3c/webappsec-permissions-policy#482

This CL is part of a series:
(1) Add function to detect subdomain matches
(2) Use OriginWithPossibleWildcards in policy
(3) Propagate node source to allow list parser
(4) Parse wildcard subdomain matches
(5) Support wildcards in getAllowlistForFeature
(6) Add WPTs
(7) Enable by default

Bug: 1345994
Change-Id: Ic8dc79be3262cdd872987c818ce01e959cdce83a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3934705
Commit-Queue: Ari Chivukula <arichiv@chromium.org>
Reviewed-by: Ian Clelland <iclelland@chromium.org>
Auto-Submit: Ari Chivukula <arichiv@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1056237}
NOKEYCHECK=True
GitOrigin-RevId: 4e770fa6e25f3013049ec3cb20dab57a9dc07f71
  • Loading branch information
arichiv authored and Copybara-Service committed Oct 7, 2022
1 parent 663d798 commit 4719c74
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// TODO(crbug.com/1345994): Add seed corpus w/ wildcards.
static blink::BlinkFuzzerTestSupport test_support =
blink::BlinkFuzzerTestSupport();
blink::PolicyParserMessageBuffer logger;
// TODO(csharrison): Be smarter about parsing these origins for performance.
scoped_refptr<const blink::SecurityOrigin> parent_origin =
blink::SecurityOrigin::CreateFromString("https://example.com/");
scoped_refptr<const blink::SecurityOrigin> child_origin =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "third_party/blink/renderer/platform/wtf/vector.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// TODO(crbug.com/1345994): Add seed corpus w/ wildcards.
static blink::BlinkFuzzerTestSupport test_support =
blink::BlinkFuzzerTestSupport();
blink::PolicyParserMessageBuffer logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#include <utility>

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "net/http/structured_headers.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/permissions_policy/origin_with_possible_wildcards.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
Expand Down Expand Up @@ -315,6 +317,11 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
// attribute.)
url::Origin target_origin;

// Determine if there is a wildcard subdomain in the target origin
// (e.g., https://*.google.com).
bool has_subdomain_wildcard = false;
wtf_size_t wildcard_pos = kNotFound;

// If the iframe will have an opaque origin (for example, if it is
// sandboxed, or has a data: URL), then 'src' needs to refer to the
// opaque origin of the frame, which is not known yet. In this case,
Expand Down Expand Up @@ -345,6 +352,30 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
allowlist_includes_star_ = true;
target_is_all = true;
}
// If there's a subdomain wildcard in the `origin_string` of a permissions
// policy, then we can parse it out and update `has_subdomain_wildcard`.
// We know there's a subdomain wildcard because there is a exactly one `*`
// and it's after the scheme and before the rest of the host.
else if (base::FeatureList::IsEnabled(
features::kWildcardSubdomainsInPermissionsPolicy) &&
type == PermissionsPolicyParser::NodeType::kHeader &&
(wildcard_pos = origin_string.Find("://*.")) != kNotFound &&
origin_string.find('*') == origin_string.ReverseFind('*')) {
// We need a copy as Remove modifies the original.
String origin_string_copy(origin_string);
origin_string_copy.Remove(wildcard_pos + 3, 2);
scoped_refptr<SecurityOrigin> parsed_origin =
SecurityOrigin::CreateFromString(origin_string_copy);
if (!parsed_origin->IsOpaque()) {
target_origin = parsed_origin->ToUrlOrigin();
has_subdomain_wildcard = true;
allowlist_includes_origin_ = true;
} else {
logger_.Warn("Unrecognized origin with subdomain wildcard: '" +
origin_string + "'.");
continue;
}
}
// Otherwise, parse the origin string and verify that the result is
// valid. Invalid strings will produce an opaque origin, which will
// result in an error message.
Expand All @@ -366,11 +397,8 @@ ParsingContext::ParsedAllowlist ParsingContext::ParseAllowlist(
} else if (target_is_opaque) {
allowlist.matches_opaque_src = true;
} else {
// TODO(crbug.com/1345994): Support wildcard matching when type is
// kHeader.
allowlist.allowed_origins.emplace_back(
target_origin,
/*has_subdomain_wildcard=*/false);
allowlist.allowed_origins.emplace_back(target_origin,
has_subdomain_wildcard);
}
}
}
Expand Down

0 comments on commit 4719c74

Please sign in to comment.