Skip to content

Commit a30d683

Browse files
csharrisonCommit bot
authored and
Commit bot
committed
[subresource_filter] Decide UNSUPPORTED_SCHEME only if we'd otherwise activate
Right now the subresource filter reports UNSUPPORTED_SCHEME even if the feature is disabled and the navigation would never have activated. This patch aligns things closer to how they were before [1] landed, so that UNSUPPORTED_SCHEME is not logged if the matched configuration's activation level is DISABLED or there is no matched configuration. BUG=todo Review-Url: https://codereview.chromium.org/2888163002 Cr-Commit-Position: refs/heads/master@{#473093}
1 parent f416664 commit a30d683

File tree

4 files changed

+81
-11
lines changed

4 files changed

+81
-11
lines changed

chrome/browser/subresource_filter/subresource_filter_unittest.cc

+40
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "components/subresource_filter/core/browser/ruleset_service.h"
3434
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
3535
#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
36+
#include "components/subresource_filter/core/common/activation_decision.h"
3637
#include "components/subresource_filter/core/common/test_ruleset_creator.h"
3738
#include "content/public/browser/navigation_throttle.h"
3839
#include "content/public/test/navigation_simulator.h"
@@ -256,3 +257,42 @@ TEST_F(SubresourceFilterTest, ExplicitWhitelisting_ShouldNotClearMetadata) {
256257
// blacklist.
257258
EXPECT_NE(nullptr, settings_manager()->GetSiteMetadata(url));
258259
}
260+
261+
TEST_F(SubresourceFilterTest,
262+
NavigationToBadSchemeUrlWithNoActivation_DoesNotReportBadScheme) {
263+
// Don't report UNSUPPORTED_SCHEME if the navigation has no matching
264+
// configuration.
265+
scoped_configuration().ResetConfiguration(subresource_filter::Configuration(
266+
subresource_filter::ActivationLevel::DISABLED,
267+
subresource_filter::ActivationScope::NO_SITES));
268+
269+
GURL url("data:text/html,hello world");
270+
SimulateNavigateAndCommit(url, main_rfh());
271+
EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh()));
272+
auto* driver_factory = subresource_filter::
273+
ContentSubresourceFilterDriverFactory::FromWebContents(web_contents());
274+
EXPECT_EQ(
275+
subresource_filter::ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
276+
driver_factory->GetActivationDecisionForLastCommittedPageLoad());
277+
278+
// Also don't report UNSUPPORTED_SCHEME if the navigation matches a
279+
// configuration with DISABLED activation level.
280+
scoped_configuration().ResetConfiguration(subresource_filter::Configuration(
281+
subresource_filter::ActivationLevel::DISABLED,
282+
subresource_filter::ActivationScope::ALL_SITES));
283+
284+
SimulateNavigateAndCommit(url, main_rfh());
285+
EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh()));
286+
EXPECT_EQ(subresource_filter::ActivationDecision::ACTIVATION_DISABLED,
287+
driver_factory->GetActivationDecisionForLastCommittedPageLoad());
288+
289+
// Sanity check that UNSUPPORTED_SCHEME is reported if the navigation does
290+
// activate.
291+
scoped_configuration().ResetConfiguration(subresource_filter::Configuration(
292+
subresource_filter::ActivationLevel::ENABLED,
293+
subresource_filter::ActivationScope::ALL_SITES));
294+
SimulateNavigateAndCommit(url, main_rfh());
295+
EXPECT_TRUE(CreateAndNavigateDisallowedSubframe(main_rfh()));
296+
EXPECT_EQ(subresource_filter::ActivationDecision::UNSUPPORTED_SCHEME,
297+
driver_factory->GetActivationDecisionForLastCommittedPageLoad());
298+
}

components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc

+29-9
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,28 @@ void ContentSubresourceFilterDriverFactory::OnSafeBrowsingMatchComputed(
127127
throttle_manager_->NotifyPageActivationComputed(navigation_handle, state);
128128
}
129129

130+
// Be careful when modifying this method, as the order in which the
131+
// activation_decision_ is decided is very important and corresponds to UMA
132+
// metrics. In general we want to follow the pattern that
133+
// ACTIVATION_CONDITIONS_NOT_MET will always be logged if no configuration
134+
// matches this navigation. We log other decisions only if a configuration
135+
// matches and also would have activated.
130136
void ContentSubresourceFilterDriverFactory::
131137
ComputeActivationForMainFrameNavigation(
132138
content::NavigationHandle* navigation_handle,
133139
ActivationList matched_list) {
134140
const GURL& url(navigation_handle->GetURL());
135141

136-
if (!url.SchemeIsHTTPOrHTTPS()) {
137-
activation_decision_ = ActivationDecision::UNSUPPORTED_SCHEME;
138-
activation_options_ = Configuration::ActivationOptions();
139-
return;
140-
}
141-
142+
bool scheme_is_http_or_https = url.SchemeIsHTTPOrHTTPS();
142143
const auto config_list = GetEnabledConfigurations();
143144
const auto highest_priority_activated_config =
144145
std::find_if(config_list->configs_by_decreasing_priority().begin(),
145146
config_list->configs_by_decreasing_priority().end(),
146-
[&url, matched_list, this](const Configuration& config) {
147+
[&url, scheme_is_http_or_https, matched_list,
148+
this](const Configuration& config) {
147149
return DoesMainFrameURLSatisfyActivationConditions(
148-
url, config.activation_conditions, matched_list);
150+
url, scheme_is_http_or_https,
151+
config.activation_conditions, matched_list);
149152
});
150153

151154
bool has_activated_config =
@@ -164,7 +167,18 @@ void ContentSubresourceFilterDriverFactory::
164167
return;
165168
}
166169

167-
activation_options_ = highest_priority_activated_config->activation_options;
170+
const Configuration::ActivationOptions& activation_options =
171+
highest_priority_activated_config->activation_options;
172+
173+
// Log UNSUPPORTED_SCHEME if we would have otherwise activated.
174+
if (!scheme_is_http_or_https &&
175+
activation_options.activation_level != ActivationLevel::DISABLED) {
176+
activation_decision_ = ActivationDecision::UNSUPPORTED_SCHEME;
177+
activation_options_ = Configuration::ActivationOptions();
178+
return;
179+
}
180+
181+
activation_options_ = activation_options;
168182
activation_decision_ =
169183
activation_options_.activation_level == ActivationLevel::DISABLED
170184
? ActivationDecision::ACTIVATION_DISABLED
@@ -174,12 +188,18 @@ void ContentSubresourceFilterDriverFactory::
174188
bool ContentSubresourceFilterDriverFactory::
175189
DoesMainFrameURLSatisfyActivationConditions(
176190
const GURL& url,
191+
bool scheme_is_http_or_https,
177192
const Configuration::ActivationConditions& conditions,
178193
ActivationList matched_list) const {
194+
// scheme_is_http_or_https implies url.SchemeIsHTTPOrHTTPS().
195+
DCHECK(!scheme_is_http_or_https || url.SchemeIsHTTPOrHTTPS());
179196
switch (conditions.activation_scope) {
180197
case ActivationScope::ALL_SITES:
181198
return true;
182199
case ActivationScope::ACTIVATION_LIST:
200+
// ACTIVATION_LIST does not support non http/s URLs.
201+
if (!scheme_is_http_or_https)
202+
return false;
183203
if (conditions.activation_list == matched_list)
184204
return true;
185205
if (conditions.activation_list == ActivationList::PHISHING_INTERSTITIAL &&

components/subresource_filter/content/browser/content_subresource_filter_driver_factory.h

+2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ class ContentSubresourceFilterDriverFactory
101101

102102
// Returns whether a main-frame navigation to the given |url| satisfies the
103103
// activation |conditions| of a given configuration, except for |priority|.
104+
// Pass |scheme_is_http_or_https| to avoid multiple string comparisons.
104105
bool DoesMainFrameURLSatisfyActivationConditions(
105106
const GURL& url,
107+
bool scheme_is_http_or_https,
106108
const Configuration::ActivationConditions& conditions,
107109
ActivationList matched_list) const;
108110

components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc

+10-2
Original file line numberDiff line numberDiff line change
@@ -734,9 +734,17 @@ TEST_P(ContentSubresourceFilterDriverFactoryActivationScopeTest,
734734
"https://example.test"};
735735
for (auto* url : unsupported_urls) {
736736
SCOPED_TRACE(url);
737+
ActivationDecision expected_decision =
738+
ActivationDecision::UNSUPPORTED_SCHEME;
739+
// We only log UNSUPPORTED_SCHEME if the navigation would have otherwise
740+
// activated. Note that non http/s URLs will never match an activation list.
741+
if (test_data.expected_activation_decision ==
742+
ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET ||
743+
test_data.activation_scope == ActivationScope::ACTIVATION_LIST) {
744+
expected_decision = ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET;
745+
}
737746
NavigateAndExpectActivation({test_data.url_matches_activation_list},
738-
{GURL(url)},
739-
ActivationDecision::UNSUPPORTED_SCHEME);
747+
{GURL(url)}, expected_decision);
740748
}
741749
for (auto* url : supported_urls) {
742750
SCOPED_TRACE(url);

0 commit comments

Comments
 (0)