Commit 2185e1dc authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

Support populating the CORB/CORS allowlist via field trial parameter.

In the past, CORB allowlist could be controlled via a field trial
parameter, but that is no longer possible since r692251.  This CL
introduces a new, separate field trial parameter that can provide
similar functionality for the AllowlistAlsoAppliesToOorCors feature.

A *separate* field trial parameter is desirable because we want to
separately control 1) the old CORB allowlist that is distributed via a
field trial to old Chrome versions and 2) the new CORB+CORS allowlist
that will be distributed to new/future Chrome versions.

Bug: 920638
Change-Id: I65af7ddbc2387765b944bf1dfb05a22b1b8555c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1995925
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734255}
parent 96186af9
......@@ -57,6 +57,13 @@ enum TestParam {
const char kCorsErrorWhenFetching[] = "error: TypeError: Failed to fetch";
// The manifest.json used below has a "key" entry that will result in the hash
// of extension id that is captured in kExpectedHashedExtensionId. Knowing
// the hash constant helps with simulating distributing the hash via field trial
// param.
const char kExpectedHashedExtensionId[] =
"14B587526D9AC6ADCACAA8A4AAE3DB281CA2AB53";
} // namespace
using CORBAction = network::CrossOriginReadBlocking::Action;
......@@ -93,6 +100,7 @@ class CrossOriginReadBlockingExtensionTest : public ExtensionBrowserTest {
const char kManifestTemplate[] = R"(
{
"name": "CrossOriginReadBlockingTest - Extension",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjzv7dI7Ygyh67VHE1DdidudpYf8PFfv8iucWvzO+3xpF/Dm5xNo7aQhPNiEaNfHwJQ7lsp4gc+C+4bbaVewBFspTruoSJhZc5uEfqxwovJwN+v1/SUFXTXQmQBv6gs0qZB4gBbl4caNQBlqrFwAMNisnu1V6UROna8rOJQ90D7Nv7TCwoVPKBfVshpFjdDOTeBg4iLctO3S/06QYqaTDrwVceSyHkVkvzBY6tc6mnYX0RZu78J9iL8bdqwfllOhs69cqoHHgrLdI6JdOyiuh6pBP6vxMlzSKWJ3YTNjaQTPwfOYaLMuzdl0v+YdzafIzV9zwe4Xiskk+5JNGt8b2rQIDAQAB",
"version": "1.0",
"manifest_version": 2,
"permissions": [
......@@ -364,22 +372,33 @@ class CrossOriginReadBlockingExtensionAllowlistingTest
CrossOriginReadBlockingExtensionAllowlistingTest() {
std::vector<base::Feature> disabled_features;
std::vector<base::Feature> enabled_features;
std::vector<base::test::ScopedFeatureList::FeatureAndParams>
enabled_features;
if (IsOutOfBlinkCorsEnabled())
enabled_features.push_back(network::features::kOutOfBlinkCors);
else
if (IsOutOfBlinkCorsEnabled()) {
enabled_features.emplace_back(network::features::kOutOfBlinkCors,
base::FieldTrialParams());
} else {
disabled_features.push_back(network::features::kOutOfBlinkCors);
}
if (ShouldAllowlistAlsoApplyToOorCors()) {
enabled_features.push_back(
extensions_features::kCorbAllowlistAlsoAppliesToOorCors);
base::FieldTrialParams field_trial_params;
if (IsExtensionAllowlisted()) {
field_trial_params.emplace(
extensions_features::kCorbAllowlistAlsoAppliesToOorCorsParamName,
kExpectedHashedExtensionId);
}
enabled_features.emplace_back(
extensions_features::kCorbAllowlistAlsoAppliesToOorCors,
field_trial_params);
} else {
disabled_features.push_back(
extensions_features::kCorbAllowlistAlsoAppliesToOorCors);
}
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
disabled_features);
}
bool IsExtensionAllowlisted() {
......@@ -399,13 +418,25 @@ class CrossOriginReadBlockingExtensionAllowlistingTest
const Extension* extension = Base::InstallExtension(
resource_to_fetch_from_declarative_content_script);
if (IsExtensionAllowlisted()) {
URLLoaderFactoryManager::AddExtensionToAllowlistForTesting(*extension);
} else {
URLLoaderFactoryManager::RemoveExtensionFromAllowlistForTesting(
*extension);
// The allowlist is populated via
// 1. Field trial param (only if ShouldAllowlistAlsoApplyToOorCors)
// 2. Hardcoded list (all cases).
// If path #1 is unavailable (i.e. if base::FieldTrialParams was not
// populated in the constructor of the test suite), then the test needs to
// modify the hardcoded list via Add/RemoveExtensionFromAllowlistForTesting.
if (!ShouldAllowlistAlsoApplyToOorCors()) {
if (IsExtensionAllowlisted()) {
URLLoaderFactoryManager::AddExtensionToAllowlistForTesting(*extension);
} else {
URLLoaderFactoryManager::RemoveExtensionFromAllowlistForTesting(
*extension);
}
}
// Sanity check that the field trial param (which has to be registered via
// ScopedFeatureList early) uses the right extension id hash.
EXPECT_EQ(kExpectedHashedExtensionId, extension->hashed_id().value());
return extension;
}
......
......@@ -262,6 +262,24 @@ std::vector<std::string> CreateExtensionAllowlist() {
allowlist.push_back(std::string(hash, kHashedExtensionIdLength));
}
// Append extensions from the field trial param.
std::string field_trial_arg = base::GetFieldTrialParamValueByFeature(
extensions_features::kCorbAllowlistAlsoAppliesToOorCors,
extensions_features::kCorbAllowlistAlsoAppliesToOorCorsParamName);
field_trial_arg = base::ToUpperASCII(field_trial_arg);
std::vector<std::string> field_trial_allowlist = base::SplitString(
field_trial_arg, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
base::EraseIf(field_trial_allowlist, [](const std::string& hash) {
// Filter out invalid data from |field_trial_allowlist|.
if (IsValidHashedExtensionId(hash))
return false; // Don't remove.
LOG(ERROR) << "Invalid extension hash: " << hash;
return true; // Remove.
});
std::move(field_trial_allowlist.begin(), field_trial_allowlist.end(),
std::back_inserter(allowlist));
return allowlist;
}
......
......@@ -36,6 +36,8 @@ const char kNeutralMessage[] = "2";
// https://www.chromium.org/Home/chromium-security/extension-content-script-fetches
const base::Feature kCorbAllowlistAlsoAppliesToOorCors{
"CorbAllowlistAlsoAppliesToOorCors", base::FEATURE_DISABLED_BY_DEFAULT};
const char kCorbAllowlistAlsoAppliesToOorCorsParamName[] =
"AllowlistForCorbAndCors";
// Forces requests to go through WebRequestProxyingURLLoaderFactory.
const base::Feature kForceWebRequestProxyForTest{
......
......@@ -19,6 +19,8 @@ extern const char kPrivacyMessage[];
extern const char kNeutralMessage[];
extern const base::Feature kCorbAllowlistAlsoAppliesToOorCors;
extern const char kCorbAllowlistAlsoAppliesToOorCorsParamName[];
extern const base::Feature kForceWebRequestProxyForTest;
} // namespace extensions_features
......
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