Commit 532a2f5d authored by Titouan Rigoudy's avatar Titouan Rigoudy Committed by Commit Bot

[CORS-RFC1918] Cover all cases with UseCounters.

This change does away with the existing
LoopbackEmbeddedIn(Non)SecureContext WebFeature, replacing it with more
specific versions for each combination of:

 (client address space, resource address space, secure context bit)

Note that this UseCounter only counts resources that were allowed
through by CORS-RFC1918 checks in services/network.

Fixed: chromium:1124358
Change-Id: I74ba85650c274779417f7c088180f482e6475981
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2424246
Commit-Queue: Titouan Rigoudy <titouan@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811186}
parent 5f33818a
......@@ -1136,8 +1136,6 @@ enum WebFeature {
kRTCPeerConnectionCreateDataChannelMaxRetransmits = 1649,
kAudioContextCreateConstantSource = 1650,
kWebAudioConstantSourceNode = 1651,
kLoopbackEmbeddedInSecureContext = 1652,
kLoopbackEmbeddedInNonSecureContext = 1653,
kBlinkMacSystemFont = 1654,
kRTCIceServerURL = 1656,
kRTCIceServerURLs = 1657,
......@@ -3015,6 +3013,16 @@ enum WebFeature {
kXRDepthInformationGetDepth = 3685,
kXRDepthInformationDataAttribute = 3686,
kInterestCohortAPI_interestCohort_Method = 3687,
kAddressSpaceLocalEmbeddedInPrivateSecureContext = 3688,
kAddressSpaceLocalEmbeddedInPrivateNonSecureContext = 3689,
kAddressSpaceLocalEmbeddedInPublicSecureContext = 3690,
kAddressSpaceLocalEmbeddedInPublicNonSecureContext = 3691,
kAddressSpaceLocalEmbeddedInUnknownSecureContext = 3692,
kAddressSpaceLocalEmbeddedInUnknownNonSecureContext = 3693,
kAddressSpacePrivateEmbeddedInPublicSecureContext = 3694,
kAddressSpacePrivateEmbeddedInPublicNonSecureContext = 3695,
kAddressSpacePrivateEmbeddedInUnknownSecureContext = 3696,
kAddressSpacePrivateEmbeddedInUnknownNonSecureContext = 3697,
// Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots.
......
......@@ -1266,6 +1266,7 @@ source_set("unit_tests") {
"layout/svg/layout_svg_text_test.cc",
"layout/text_autosizer_test.cc",
"layout/visual_rect_mapping_test.cc",
"loader/address_space_feature_test.cc",
"loader/alternate_signed_exchange_resource_info_test.cc",
"loader/base_fetch_context_test.cc",
"loader/document_load_timing_test.cc",
......
......@@ -6,6 +6,8 @@ import("//third_party/blink/renderer/core/core.gni")
blink_core_sources("loader") {
sources = [
"address_space_feature.cc",
"address_space_feature.h",
"alternate_signed_exchange_resource_info.cc",
"alternate_signed_exchange_resource_info.h",
"appcache/application_cache.cc",
......
/*
* Copyright (C) 2020 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/core/loader/address_space_feature.h"
namespace blink {
using AddressSpace = network::mojom::blink::IPAddressSpace;
using Feature = mojom::blink::WebFeature;
// Returns the kAddressSpaceLocal* WebFeature enum value corresponding to the
// given client loading a resource from the local address space, if any.
base::Optional<Feature> AddressSpaceLocalFeature(
AddressSpace client_address_space,
bool client_is_secure_context) {
switch (client_address_space) {
case AddressSpace::kUnknown:
return client_is_secure_context
? Feature::kAddressSpaceLocalEmbeddedInUnknownSecureContext
: Feature::kAddressSpaceLocalEmbeddedInUnknownNonSecureContext;
case AddressSpace::kPublic:
return client_is_secure_context
? Feature::kAddressSpaceLocalEmbeddedInPublicSecureContext
: Feature::kAddressSpaceLocalEmbeddedInPublicNonSecureContext;
case AddressSpace::kPrivate:
return client_is_secure_context
? Feature::kAddressSpaceLocalEmbeddedInPrivateSecureContext
: Feature::kAddressSpaceLocalEmbeddedInPrivateNonSecureContext;
case AddressSpace::kLocal:
return base::nullopt; // Local to local is fine, we do not track it.
}
}
// Returns the kAddressSpacePrivate* WebFeature enum value corresponding to the
// given client loading a resource from the private address space, if any.
base::Optional<Feature> AddressSpacePrivateFeature(
AddressSpace client_address_space,
bool client_is_secure_context) {
switch (client_address_space) {
case AddressSpace::kUnknown:
return client_is_secure_context
? Feature::kAddressSpacePrivateEmbeddedInUnknownSecureContext
: Feature::
kAddressSpacePrivateEmbeddedInUnknownNonSecureContext;
case AddressSpace::kPublic:
return client_is_secure_context
? Feature::kAddressSpacePrivateEmbeddedInPublicSecureContext
: Feature::
kAddressSpacePrivateEmbeddedInPublicNonSecureContext;
case AddressSpace::kPrivate:
case AddressSpace::kLocal:
// Private or local to local is fine, we do not track it.
return base::nullopt;
}
}
base::Optional<Feature> AddressSpaceFeature(
AddressSpace client_address_space,
bool client_is_secure_context,
AddressSpace resource_address_space) {
switch (resource_address_space) {
case AddressSpace::kUnknown:
case AddressSpace::kPublic:
return base::nullopt;
case AddressSpace::kPrivate:
return AddressSpacePrivateFeature(client_address_space,
client_is_secure_context);
case AddressSpace::kLocal:
return AddressSpaceLocalFeature(client_address_space,
client_is_secure_context);
}
}
} // namespace blink
/*
* Copyright (C) 2020 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_ADDRESS_SPACE_FEATURE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_ADDRESS_SPACE_FEATURE_H_
#include "base/optional.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
namespace blink {
// Returns the kAddressSpace* WebFeature enum value corresponding to a client
// in |client_address_space| loading a resource from |resource_address_space|,
// if any.
//
// |client_is_secure_context| specifies whether the client execution context is
// a secure context, as defined in
// https://html.spec.whatwg.org/multipage/webappapis.html#secure-context.
//
// Returns nullopt if the load is not a private network request, as defined in
// https://wicg.github.io/cors-rfc1918/#private-network-request.
base::Optional<mojom::blink::WebFeature> CORE_EXPORT AddressSpaceFeature(
network::mojom::blink::IPAddressSpace client_address_space,
bool client_is_secure_context,
network::mojom::blink::IPAddressSpace resource_address_space);
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_ADDRESS_SPACE_FEATURE_H_
/*
* Copyright (C) 2020 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "third_party/blink/renderer/core/loader/address_space_feature.h"
#include <iosfwd>
#include <vector>
#include "services/network/public/cpp/ip_address_space_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
namespace {
using AddressSpace = network::mojom::blink::IPAddressSpace;
using Feature = mojom::blink::WebFeature;
constexpr AddressSpace kAllAddressSpaces[] = {
AddressSpace::kUnknown,
AddressSpace::kPublic,
AddressSpace::kPrivate,
AddressSpace::kLocal,
};
// Encapsulates arguments to AddressSpaceFeature.
struct Input {
AddressSpace client_address_space;
bool client_is_secure_context;
AddressSpace resource_address_space;
};
// Convenience for HasMappedFeature().
bool operator==(const Input& lhs, const Input& rhs) {
return lhs.client_address_space == rhs.client_address_space &&
lhs.client_is_secure_context == rhs.client_is_secure_context &&
lhs.resource_address_space == rhs.resource_address_space;
}
// Allows use of Input arguments to SCOPED_TRACE().
std::ostream& operator<<(std::ostream& out, const Input& input) {
return out << "Input{ client_address_space: " << input.client_address_space
<< ", client_is_secure_context: " << input.client_is_secure_context
<< ", resource_address_space: " << input.resource_address_space
<< " }";
}
// Returns all possible Input values.
std::vector<Input> AllInputs() {
std::vector<Input> result;
for (AddressSpace client_address_space : kAllAddressSpaces) {
for (bool client_is_secure_context : {false, true}) {
for (AddressSpace resource_address_space : kAllAddressSpaces) {
result.push_back({
client_address_space,
client_is_secure_context,
resource_address_space,
});
}
}
}
return result;
}
// Convenience: calls AddressSpaceFeature() on input's components.
base::Optional<Feature> AddressSpaceFeatureForInput(const Input& input) {
return AddressSpaceFeature(input.client_address_space,
input.client_is_secure_context,
input.resource_address_space);
}
// Maps an input to an expected Feature value.
struct FeatureMapping {
Input input;
Feature feature;
};
// The list of all features and their mapped inputs.
constexpr FeatureMapping kFeatureMappings[] = {
{
{AddressSpace::kUnknown, false, AddressSpace::kPrivate},
Feature::kAddressSpacePrivateEmbeddedInUnknownNonSecureContext,
},
{
{AddressSpace::kUnknown, true, AddressSpace::kPrivate},
Feature::kAddressSpacePrivateEmbeddedInUnknownSecureContext,
},
{
{AddressSpace::kUnknown, false, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInUnknownNonSecureContext,
},
{
{AddressSpace::kUnknown, true, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInUnknownSecureContext,
},
{
{AddressSpace::kPublic, false, AddressSpace::kPrivate},
Feature::kAddressSpacePrivateEmbeddedInPublicNonSecureContext,
},
{
{AddressSpace::kPublic, true, AddressSpace::kPrivate},
Feature::kAddressSpacePrivateEmbeddedInPublicSecureContext,
},
{
{AddressSpace::kPublic, false, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInPublicNonSecureContext,
},
{
{AddressSpace::kPublic, true, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInPublicSecureContext,
},
{
{AddressSpace::kPrivate, false, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInPrivateNonSecureContext,
},
{
{AddressSpace::kPrivate, true, AddressSpace::kLocal},
Feature::kAddressSpaceLocalEmbeddedInPrivateSecureContext,
},
};
// Returns true if input is mapped to a feature in kFeatureMappings.
bool HasMappedFeature(const Input& input) {
for (const FeatureMapping& mapping : kFeatureMappings) {
if (input == mapping.input) {
return true;
}
}
return false;
}
// This test verifies that AddressSpaceFeature stays in sync with the reference
// implementation for CORS-RFC1918 address space checks in services/network. In
// more practical terms, it verifies that AddressSpaceFeature returns a feature
// (as opposed to nullopt) if and only if the resource address space is less
// public than the client address space.
TEST(AddressSpaceFeatureTest, ReturnsFeatureIffResourceLessPublic) {
for (const Input& input : AllInputs()) {
SCOPED_TRACE(input);
auto optional_feature = AddressSpaceFeatureForInput(input);
bool should_have_feature = network::IsLessPublicAddressSpace(
input.resource_address_space, input.client_address_space);
if (should_have_feature) {
EXPECT_TRUE(optional_feature.has_value());
} else {
EXPECT_FALSE(optional_feature.has_value()) << *optional_feature;
}
}
}
// This test verifies that AddressSpaceFeature() maps inputs to features as
// declared in kFeatureMappings.
TEST(AddressSpaceFeatureTest, MapsAllFeaturesCorrectly) {
for (const FeatureMapping& mapping : kFeatureMappings) {
SCOPED_TRACE(mapping.input);
auto optional_feature = AddressSpaceFeatureForInput(mapping.input);
ASSERT_TRUE(optional_feature.has_value());
EXPECT_EQ(mapping.feature, *optional_feature);
}
}
// This test verifies that all inputs that yield a Feature when run through
// AddressSpaceFeature() are included in kFeatureMappings.
TEST(AddressSpaceFeatureTest, FeatureMappingsAreComplete) {
for (const Input& input : AllInputs()) {
SCOPED_TRACE(input);
auto optional_feature = AddressSpaceFeatureForInput(input);
if (HasMappedFeature(input)) {
EXPECT_TRUE(optional_feature.has_value());
} else {
EXPECT_FALSE(optional_feature.has_value()) << *optional_feature;
}
}
}
} // namespace
} // namespace blink
......@@ -30,8 +30,7 @@
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "services/network/public/cpp/ip_address_space_util.h"
#include "services/network/public/mojom/ip_address_space.mojom-blink.h"
#include "base/optional.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/security_context/insecure_request_policy.h"
#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink.h"
......@@ -47,6 +46,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/loader/address_space_feature.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_fetch_context.h"
#include "third_party/blink/renderer/core/loader/worker_fetch_context.h"
......@@ -791,20 +791,17 @@ void MixedContentChecker::CheckMixedPrivatePublic(
return;
LocalDOMWindow* window = frame->DomWindow();
if (!network::IsLessPublicAddressSpace(response.AddressSpace(),
window->AddressSpace())) {
return; // Not a private network request.
base::Optional<WebFeature> feature =
AddressSpaceFeature(window->AddressSpace(), window->IsSecureContext(),
response.AddressSpace());
if (!feature.has_value()) {
return;
}
// This WebFeature encompasses all private network requests.
UseCounter::Count(window,
WebFeature::kMixedContentPrivateHostnameInPublicHostname);
if (response.AddressSpace() == network::mojom::IPAddressSpace::kLocal) {
UseCounter::Count(window,
window->IsSecureContext()
? WebFeature::kLoopbackEmbeddedInSecureContext
: WebFeature::kLoopbackEmbeddedInNonSecureContext);
}
UseCounter::Count(window, *feature);
}
void MixedContentChecker::HandleCertificateError(
......
......@@ -27335,8 +27335,8 @@ Called by update_use_counter_feature_enum.py.-->
<int value="1649" label="RTCPeerConnectionCreateDataChannelMaxRetransmits"/>
<int value="1650" label="AudioContextCreateConstantSource"/>
<int value="1651" label="WebAudioConstantSourceNode"/>
<int value="1652" label="LoopbackEmbeddedInSecureContext"/>
<int value="1653" label="LoopbackEmbeddedInNonSecureContext"/>
<int value="1652" label="OBSOLETE_LoopbackEmbeddedInSecureContext"/>
<int value="1653" label="OBSOLETE_LoopbackEmbeddedInNonSecureContext"/>
<int value="1654" label="BlinkMacSystemFont"/>
<int value="1655" label="RTCConfigurationIceTransportsNone"/>
<int value="1656" label="RTCIceServerURL"/>
......@@ -29475,6 +29475,18 @@ Called by update_use_counter_feature_enum.py.-->
<int value="3685" label="XRDepthInformationGetDepth"/>
<int value="3686" label="XRDepthInformationDataAttribute"/>
<int value="3687" label="InterestCohortAPI_interestCohort_Method"/>
<int value="3688" label="AddressSpaceLocalEmbeddedInPrivateSecureContext"/>
<int value="3689" label="AddressSpaceLocalEmbeddedInPrivateNonSecureContext"/>
<int value="3690" label="AddressSpaceLocalEmbeddedInPublicSecureContext"/>
<int value="3691" label="AddressSpaceLocalEmbeddedInPublicNonSecureContext"/>
<int value="3692" label="AddressSpaceLocalEmbeddedInUnknownSecureContext"/>
<int value="3693" label="AddressSpaceLocalEmbeddedInUnknownNonSecureContext"/>
<int value="3694" label="AddressSpacePrivateEmbeddedInPublicSecureContext"/>
<int value="3695"
label="AddressSpacePrivateEmbeddedInPublicNonSecureContext"/>
<int value="3696" label="AddressSpacePrivateEmbeddedInUnknownSecureContext"/>
<int value="3697"
label="AddressSpacePrivateEmbeddedInUnknownNonSecureContext"/>
</enum>
<enum name="FeaturePolicyAllowlistType">
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