| Index: components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
|
| diff --git a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
|
| index e2605f8fc08d9f91c5c5bdd85bbf32fcb10eec4e..deec7ecc55eb49d03fbe5540adf9eb9680265971 100644
|
| --- a/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
|
| +++ b/components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle_unittest.cc
|
| @@ -5,8 +5,11 @@
|
| #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_activation_throttle.h"
|
|
|
| #include <memory>
|
| +#include <set>
|
| +#include <string>
|
| #include <tuple>
|
| #include <utility>
|
| +#include <vector>
|
|
|
| #include "base/memory/ptr_util.h"
|
| #include "base/metrics/field_trial.h"
|
| @@ -19,6 +22,7 @@
|
| #include "components/subresource_filter/content/browser/subresource_filter_client.h"
|
| #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h"
|
| #include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client_request.h"
|
| +#include "components/subresource_filter/content/browser/verified_ruleset_dealer.h"
|
| #include "components/subresource_filter/core/browser/subresource_filter_features.h"
|
| #include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
|
| #include "components/subresource_filter/core/common/activation_decision.h"
|
| @@ -26,6 +30,7 @@
|
| #include "components/subresource_filter/core/common/activation_list.h"
|
| #include "components/subresource_filter/core/common/activation_state.h"
|
| #include "components/subresource_filter/core/common/test_ruleset_creator.h"
|
| +#include "components/subresource_filter/core/common/test_ruleset_utils.h"
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/navigation_handle.h"
|
| #include "content/public/browser/web_contents_observer.h"
|
| @@ -45,6 +50,7 @@ const char kUrlC[] = "https://example_c.com";
|
| const char kUrlD[] = "https://example_d.com";
|
|
|
| char kURL[] = "http://example.test/";
|
| +char kURLWithParams[] = "http://example.test/?v=10";
|
| char kRedirectURL[] = "http://redirect.test/";
|
|
|
| // Names of navigation chain patterns histogram.
|
| @@ -64,20 +70,41 @@ const char kMatchesPatternHistogramName[] =
|
| const char kNavigationChainSize[] =
|
| "SubresourceFilter.PageLoad.RedirectChainLength.";
|
|
|
| -class MockSubresourceFilterClient
|
| - : public subresource_filter::SubresourceFilterClient {
|
| +class MockSubresourceFilterClient : public SubresourceFilterClient {
|
| public:
|
| - MockSubresourceFilterClient() {}
|
| -
|
| + MockSubresourceFilterClient() = default;
|
| ~MockSubresourceFilterClient() override = default;
|
|
|
| + // Mocks have trouble with move-only types passed in the constructor.
|
| + void set_ruleset_dealer(
|
| + std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer) {
|
| + ruleset_dealer_ = std::move(ruleset_dealer);
|
| + }
|
| +
|
| + bool OnPageActivationComputed(content::NavigationHandle* handle,
|
| + bool activated) override {
|
| + DCHECK(handle->IsInMainFrame());
|
| + return whitelisted_hosts_.count(handle->GetURL().host());
|
| + }
|
| +
|
| + void WhitelistInCurrentWebContents(const GURL& url) override {
|
| + ASSERT_TRUE(url.SchemeIsHTTPOrHTTPS());
|
| + whitelisted_hosts_.insert(url.host());
|
| + }
|
| +
|
| + VerifiedRulesetDealer::Handle* GetRulesetDealer() override {
|
| + return ruleset_dealer_.get();
|
| + }
|
| +
|
| MOCK_METHOD1(ToggleNotificationVisibility, void(bool));
|
| - MOCK_METHOD2(OnPageActivationComputed,
|
| - bool(content::NavigationHandle*, bool));
|
| - MOCK_METHOD1(WhitelistInCurrentWebContents, void(const GURL&));
|
| - MOCK_METHOD0(GetRulesetDealer, VerifiedRulesetDealer::Handle*());
|
| +
|
| + void ClearWhitelist() { whitelisted_hosts_.clear(); }
|
|
|
| private:
|
| + std::set<std::string> whitelisted_hosts_;
|
| +
|
| + std::unique_ptr<VerifiedRulesetDealer::Handle> ruleset_dealer_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(MockSubresourceFilterClient);
|
| };
|
|
|
| @@ -139,8 +166,17 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| Configure();
|
| test_io_task_runner_ = new base::TestMockTimeTaskRunner();
|
| // Note: Using NiceMock to allow uninteresting calls and suppress warnings.
|
| + std::vector<proto::UrlRule> rules;
|
| + rules.push_back(testing::CreateSuffixRule("disallowed.html"));
|
| + ASSERT_NO_FATAL_FAILURE(test_ruleset_creator_.CreateRulesetWithRules(
|
| + rules, &test_ruleset_pair_));
|
| + auto ruleset_dealer = base::MakeUnique<VerifiedRulesetDealer::Handle>(
|
| + base::MessageLoop::current()->task_runner());
|
| + ruleset_dealer->SetRulesetFile(
|
| + testing::TestRuleset::Open(test_ruleset_pair_.indexed));
|
| client_ =
|
| base::MakeUnique<::testing::NiceMock<MockSubresourceFilterClient>>();
|
| + client_->set_ruleset_dealer(std::move(ruleset_dealer));
|
| ContentSubresourceFilterDriverFactory::CreateForWebContents(
|
| RenderViewHostTestHarness::web_contents(), client_.get());
|
| fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager();
|
| @@ -155,6 +191,7 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| }
|
|
|
| void TearDown() override {
|
| + client_.reset();
|
| RunUntilIdle();
|
| content::RenderViewHostTestHarness::TearDown();
|
| }
|
| @@ -167,14 +204,52 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| // content::WebContentsObserver:
|
| void DidStartNavigation(
|
| content::NavigationHandle* navigation_handle) override {
|
| - ASSERT_TRUE(navigation_handle->IsInMainFrame());
|
| - navigation_handle->RegisterThrottleForTesting(
|
| - base::MakeUnique<SubresourceFilterSafeBrowsingActivationThrottle>(
|
| - navigation_handle, test_io_task_runner_,
|
| - fake_safe_browsing_database_));
|
| + if (navigation_handle->IsInMainFrame()) {
|
| + navigation_handle->RegisterThrottleForTesting(
|
| + base::MakeUnique<SubresourceFilterSafeBrowsingActivationThrottle>(
|
| + navigation_handle, test_io_task_runner_,
|
| + fake_safe_browsing_database_));
|
| + }
|
| + std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
|
| + factory()->throttle_manager()->MaybeAppendNavigationThrottles(
|
| + navigation_handle, &throttles);
|
| + for (auto& it : throttles) {
|
| + navigation_handle->RegisterThrottleForTesting(std::move(it));
|
| + }
|
| + }
|
| +
|
| + // Returns the frame host the navigation committed in, or nullptr if it did
|
| + // not succeed.
|
| + content::RenderFrameHost* CreateAndNavigateDisallowedSubframe(
|
| + content::RenderFrameHost* parent) {
|
| + auto* subframe =
|
| + content::RenderFrameHostTester::For(parent)->AppendChild("subframe");
|
| + auto simulator = content::NavigationSimulator::CreateRendererInitiated(
|
| + GURL("https://example.test/disallowed.html"), subframe);
|
| + simulator->Commit();
|
| + return simulator->GetLastThrottleCheckResult() ==
|
| + content::NavigationThrottle::PROCEED
|
| + ? simulator->GetFinalRenderFrameHost()
|
| + : nullptr;
|
| + }
|
| +
|
| + content::RenderFrameHost* SimulateNavigateAndCommit(
|
| + std::vector<GURL> navigation_chain,
|
| + content::RenderFrameHost* rfh) {
|
| + SimulateStart(navigation_chain.front(), rfh);
|
| + for (auto it = navigation_chain.begin() + 1; it != navigation_chain.end();
|
| + ++it) {
|
| + SimulateRedirectAndExpectProceed(*it);
|
| + }
|
| + SimulateCommitAndExpectProceed();
|
| + return navigation_simulator_->GetFinalRenderFrameHost();
|
| }
|
|
|
| - content::NavigationThrottle::ThrottleCheckResult SimulateStart() {
|
| + content::NavigationThrottle::ThrottleCheckResult SimulateStart(
|
| + const GURL& first_url,
|
| + content::RenderFrameHost* rfh) {
|
| + navigation_simulator_ =
|
| + content::NavigationSimulator::CreateRendererInitiated(first_url, rfh);
|
| navigation_simulator_->Start();
|
| auto result = navigation_simulator_->GetLastThrottleCheckResult();
|
| if (result == content::NavigationThrottle::CANCEL)
|
| @@ -191,7 +266,8 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| return result;
|
| }
|
|
|
| - content::NavigationThrottle::ThrottleCheckResult SimulateCommit() {
|
| + content::NavigationThrottle::ThrottleCheckResult SimulateCommit(
|
| + content::NavigationSimulator* simulator) {
|
| // Need to post a task to flush the IO thread because calling Commit()
|
| // blocks until the throttle checks are complete.
|
| // TODO(csharrison): Consider adding finer grained control to the
|
| @@ -200,15 +276,13 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| FROM_HERE, base::Bind(&base::TestMockTimeTaskRunner::RunUntilIdle,
|
| base::Unretained(test_io_task_runner_.get())));
|
| - navigation_simulator_->Commit();
|
| - auto result = navigation_simulator_->GetLastThrottleCheckResult();
|
| - if (result == content::NavigationThrottle::CANCEL)
|
| - navigation_simulator_.reset();
|
| - return result;
|
| + simulator->Commit();
|
| + return simulator->GetLastThrottleCheckResult();
|
| }
|
|
|
| - void SimulateStartAndExpectProceed() {
|
| - EXPECT_EQ(content::NavigationThrottle::PROCEED, SimulateStart());
|
| + void SimulateStartAndExpectProceed(const GURL& first_url) {
|
| + EXPECT_EQ(content::NavigationThrottle::PROCEED,
|
| + SimulateStart(first_url, main_rfh()));
|
| }
|
|
|
| void SimulateRedirectAndExpectProceed(const GURL& new_url) {
|
| @@ -216,13 +290,8 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| }
|
|
|
| void SimulateCommitAndExpectProceed() {
|
| - EXPECT_EQ(content::NavigationThrottle::PROCEED, SimulateCommit());
|
| - }
|
| -
|
| - void CreateTestNavigationForMainFrame(const GURL& first_url) {
|
| - navigation_simulator_ =
|
| - content::NavigationSimulator::CreateRendererInitiated(first_url,
|
| - main_rfh());
|
| + EXPECT_EQ(content::NavigationThrottle::PROCEED,
|
| + SimulateCommit(navigation_simulator()));
|
| }
|
|
|
| void ConfigureForMatch(const GURL& url,
|
| @@ -248,8 +317,14 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| + content::NavigationSimulator* navigation_simulator() {
|
| + return navigation_simulator_.get();
|
| + }
|
| +
|
| const base::HistogramTester& tester() const { return tester_; }
|
|
|
| + MockSubresourceFilterClient* client() { return client_.get(); }
|
| +
|
| base::TestMockTimeTaskRunner* test_io_task_runner() const {
|
| return test_io_task_runner_.get();
|
| }
|
| @@ -262,8 +337,12 @@ class SubresourceFilterSafeBrowsingActivationThrottleTest
|
| base::FieldTrialList field_trial_list_;
|
| testing::ScopedSubresourceFilterConfigurator scoped_configuration_;
|
| scoped_refptr<base::TestMockTimeTaskRunner> test_io_task_runner_;
|
| +
|
| + testing::TestRulesetCreator test_ruleset_creator_;
|
| + testing::TestRulesetPair test_ruleset_pair_;
|
| +
|
| std::unique_ptr<content::NavigationSimulator> navigation_simulator_;
|
| - std::unique_ptr<SubresourceFilterClient> client_;
|
| + std::unique_ptr<MockSubresourceFilterClient> client_;
|
| scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_;
|
| base::HistogramTester tester_;
|
|
|
| @@ -331,42 +410,425 @@ class SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling
|
| SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling);
|
| };
|
|
|
| +struct ActivationScopeTestData {
|
| + ActivationDecision expected_activation_decision;
|
| + bool url_matches_activation_list;
|
| + ActivationScope activation_scope;
|
| +};
|
| +
|
| +const ActivationScopeTestData kActivationScopeTestData[] = {
|
| + {ActivationDecision::ACTIVATED, false /* url_matches_activation_list */,
|
| + ActivationScope::ALL_SITES},
|
| + {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
|
| + ActivationScope::ALL_SITES},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + true /* url_matches_activation_list */, ActivationScope::NO_SITES},
|
| + {ActivationDecision::ACTIVATED, true /* url_matches_activation_list */,
|
| + ActivationScope::ACTIVATION_LIST},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + false /* url_matches_activation_list */, ActivationScope::ACTIVATION_LIST},
|
| +};
|
| +
|
| +class SubresourceFilterSafeBrowsingActivationThrottleScopeTest
|
| + : public SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + public ::testing::WithParamInterface<ActivationScopeTestData> {
|
| + public:
|
| + SubresourceFilterSafeBrowsingActivationThrottleScopeTest() {}
|
| + ~SubresourceFilterSafeBrowsingActivationThrottleScopeTest() override {}
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(
|
| + SubresourceFilterSafeBrowsingActivationThrottleScopeTest);
|
| +};
|
| +
|
| TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| PassThroughThrottle) {
|
| UsePassThroughThrottle();
|
| - CreateTestNavigationForMainFrame(GURL(kURL));
|
| - SimulateStartAndExpectProceed();
|
| - SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
|
| - SimulateCommitAndExpectProceed();
|
| + SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
|
| EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| factory()->GetActivationDecisionForLastCommittedPageLoad());
|
|
|
| scoped_configuration()->ResetConfiguration(
|
| Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
|
| - CreateTestNavigationForMainFrame(GURL(kURL));
|
| - SimulateStartAndExpectProceed();
|
| - SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
|
| - SimulateCommitAndExpectProceed();
|
| + SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
|
| EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| factory()->GetActivationDecisionForLastCommittedPageLoad());
|
|
|
| scoped_configuration()->ResetConfiguration(
|
| Configuration(ActivationLevel::ENABLED, ActivationScope::NO_SITES));
|
| - CreateTestNavigationForMainFrame(GURL(kURL));
|
| - SimulateStartAndExpectProceed();
|
| - SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
|
| - SimulateCommitAndExpectProceed();
|
| + SimulateNavigateAndCommit({GURL(kURL), GURL(kRedirectURL)}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, NoConfigs) {
|
| + scoped_configuration()->ResetConfiguration(std::vector<Configuration>());
|
| + SimulateNavigateAndCommit({GURL(kURL)}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + MultipleSimultaneousConfigs) {
|
| + Configuration config1(ActivationLevel::DRYRUN, ActivationScope::NO_SITES);
|
| + config1.activation_conditions.priority = 2;
|
| +
|
| + Configuration config2(ActivationLevel::DISABLED,
|
| + ActivationScope::ACTIVATION_LIST,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL);
|
| + config2.activation_conditions.priority = 1;
|
| +
|
| + Configuration config3(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
|
| + config3.activation_options.should_whitelist_site_on_reload = true;
|
| + config3.activation_conditions.priority = 0;
|
| +
|
| + scoped_configuration()->ResetConfiguration({config1, config2, config3});
|
| +
|
| + // Should match |config2| and |config3|, the former with the higher priority.
|
| + GURL match_url(kUrlA);
|
| + GURL non_match_url(kUrlB);
|
| + ConfigureForMatch(match_url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS);
|
| + SimulateNavigateAndCommit({match_url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + // Should match |config3|.
|
| + SimulateNavigateAndCommit({non_match_url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + // Should match |config3|, but a reload, so this should get whitelisted.
|
| + auto reload_simulator = content::NavigationSimulator::CreateRendererInitiated(
|
| + non_match_url, main_rfh());
|
| + reload_simulator->SetTransition(ui::PAGE_TRANSITION_RELOAD);
|
| + reload_simulator->Start();
|
| + SimulateCommit(reload_simulator.get());
|
| + EXPECT_EQ(ActivationDecision::URL_WHITELISTED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + ActivationLevelDisabled_NoActivation) {
|
| + scoped_configuration()->ResetConfiguration(
|
| + Configuration(ActivationLevel::DISABLED, ActivationScope::ACTIVATION_LIST,
|
| + ActivationList::SUBRESOURCE_FILTER));
|
| + GURL url(kURL);
|
| +
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + ConfigureForMatch(url);
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + // Whitelisting occurs last, so the decision should still be DISABLED.
|
| + factory()->client()->WhitelistInCurrentWebContents(url);
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + AllSiteEnabled_Activates) {
|
| + scoped_configuration()->ResetConfiguration(
|
| + Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
|
| + GURL url(kURL);
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + ConfigureForMatch(url);
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + // Adding performance measurement should keep activation.
|
| + Configuration config_with_perf(
|
| + Configuration(ActivationLevel::ENABLED, ActivationScope::ALL_SITES));
|
| + config_with_perf.activation_options.performance_measurement_rate = 1.0;
|
| + scoped_configuration()->ResetConfiguration(std::move(config_with_perf));
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + NavigationFails_NoActivation) {
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + content::NavigationSimulator::NavigateAndFailFromDocument(
|
| + GURL(kURL), net::ERR_TIMED_OUT, main_rfh());
|
| + EXPECT_EQ(ActivationDecision::ACTIVATION_DISABLED,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + NotificationVisibility) {
|
| + GURL url(kURL);
|
| + ConfigureForMatch(url);
|
| + EXPECT_CALL(*client(), ToggleNotificationVisibility(false)).Times(1);
|
| + content::RenderFrameHost* rfh = SimulateNavigateAndCommit({url}, main_rfh());
|
| +
|
| + EXPECT_CALL(*client(), ToggleNotificationVisibility(true)).Times(1);
|
| + EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(rfh));
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + SuppressNotificationVisibility) {
|
| + Configuration config(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
|
| + config.activation_options.should_suppress_notifications = true;
|
| + scoped_configuration()->ResetConfiguration(std::move(config));
|
| +
|
| + GURL url(kURL);
|
| + content::RenderFrameHost* rfh = SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0);
|
| + EXPECT_FALSE(CreateAndNavigateDisallowedSubframe(rfh));
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + WhitelistSiteOnReload) {
|
| + const struct {
|
| + content::Referrer referrer;
|
| + ui::PageTransition transition;
|
| + ActivationDecision expected_activation_decision;
|
| + } kTestCases[] = {
|
| + {content::Referrer(), ui::PAGE_TRANSITION_LINK,
|
| + ActivationDecision::ACTIVATED},
|
| + {content::Referrer(GURL(kUrlA), blink::kWebReferrerPolicyDefault),
|
| + ui::PAGE_TRANSITION_LINK, ActivationDecision::ACTIVATED},
|
| + {content::Referrer(GURL(kURL), blink::kWebReferrerPolicyDefault),
|
| + ui::PAGE_TRANSITION_LINK, ActivationDecision::URL_WHITELISTED},
|
| + {content::Referrer(), ui::PAGE_TRANSITION_RELOAD,
|
| + ActivationDecision::URL_WHITELISTED}};
|
| +
|
| + Configuration config(ActivationLevel::ENABLED, ActivationScope::ALL_SITES);
|
| + config.activation_options.should_whitelist_site_on_reload = true;
|
| + scoped_configuration()->ResetConfiguration(std::move(config));
|
| +
|
| + for (const auto& test_case : kTestCases) {
|
| + SCOPED_TRACE(::testing::Message("referrer = \"")
|
| + << test_case.referrer.url << "\""
|
| + << " transition = \"" << test_case.transition << "\"");
|
| +
|
| + auto simulator = content::NavigationSimulator::CreateRendererInitiated(
|
| + GURL(kURL), main_rfh());
|
| + simulator->SetTransition(test_case.transition);
|
| + simulator->SetReferrer(test_case.referrer);
|
| + SimulateCommit(simulator.get());
|
| + EXPECT_EQ(test_case.expected_activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + // Verify that if the first URL failed to activate, subsequent same-origin
|
| + // navigations also fail to activate.
|
| + simulator = content::NavigationSimulator::CreateRendererInitiated(
|
| + GURL(kURLWithParams), main_rfh());
|
| + SimulateCommit(simulator.get());
|
| + EXPECT_EQ(test_case.expected_activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest,
|
| + ActivateForFrameState) {
|
| + const struct {
|
| + ActivationDecision activation_decision;
|
| + ActivationLevel activation_level;
|
| + } kTestCases[] = {
|
| + {ActivationDecision::ACTIVATED, ActivationLevel::DRYRUN},
|
| + {ActivationDecision::ACTIVATED, ActivationLevel::ENABLED},
|
| + {ActivationDecision::ACTIVATION_DISABLED, ActivationLevel::DISABLED},
|
| + };
|
| + for (const auto& test_data : kTestCases) {
|
| + SCOPED_TRACE(::testing::Message()
|
| + << "activation_decision "
|
| + << static_cast<int>(test_data.activation_decision)
|
| + << " activation_level " << test_data.activation_level);
|
| + client()->ClearWhitelist();
|
| + scoped_configuration()->ResetConfiguration(Configuration(
|
| + test_data.activation_level, ActivationScope::ACTIVATION_LIST,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL));
|
| + const GURL url(kURLWithParams);
|
| + ConfigureForMatch(url, safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS);
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(test_data.activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| +
|
| + // Whitelisting is only applied when the page will otherwise activate.
|
| + client()->WhitelistInCurrentWebContents(url);
|
| + ActivationDecision decision =
|
| + test_data.activation_level == ActivationLevel::DISABLED
|
| + ? test_data.activation_decision
|
| + : ActivationDecision::URL_WHITELISTED;
|
| + SimulateNavigateAndCommit({url}, main_rfh());
|
| + EXPECT_EQ(decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| +}
|
| +
|
| +TEST_F(SubresourceFilterSafeBrowsingActivationThrottleTest, ActivationList) {
|
| + const struct {
|
| + ActivationDecision expected_activation_decision;
|
| + ActivationList activation_list;
|
| + safe_browsing::SBThreatType threat_type;
|
| + safe_browsing::ThreatPatternType threat_type_metadata;
|
| + } kTestCases[] = {
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET, ActivationList::NONE,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::NONE},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::MALWARE_LANDING},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::MALWARE_DISTRIBUTION},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_API_ABUSE,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_BLACKLISTED_RESOURCE,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_BINARY_MALWARE_URL,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_UNWANTED,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_SAFE,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATED, ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::NONE},
|
| + {ActivationDecision::ACTIVATED,
|
| + ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATED, ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
|
| + safe_browsing::ThreatPatternType::SOCIAL_ENGINEERING_ADS},
|
| + {ActivationDecision::ACTIVATED, ActivationList::SUBRESOURCE_FILTER,
|
| + safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
|
| + safe_browsing::ThreatPatternType::NONE},
|
| + {ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| + ActivationList::PHISHING_INTERSTITIAL,
|
| + safe_browsing::SB_THREAT_TYPE_SUBRESOURCE_FILTER,
|
| + safe_browsing::ThreatPatternType::NONE},
|
| + };
|
| + const GURL test_url("https://matched_url.com/");
|
| + for (const auto& test_case : kTestCases) {
|
| + scoped_configuration()->ResetConfiguration(Configuration(
|
| + ActivationLevel::ENABLED, ActivationScope::ACTIVATION_LIST,
|
| + test_case.activation_list));
|
| + ClearAllBlacklistedUrls();
|
| + ConfigureForMatch(test_url, test_case.threat_type,
|
| + test_case.threat_type_metadata);
|
| + SimulateNavigateAndCommit({GURL(kUrlA), GURL(kUrlB), GURL(kUrlC), test_url},
|
| + main_rfh());
|
| + EXPECT_EQ(test_case.expected_activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| }
|
|
|
| +TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
|
| + ActivateForScopeType) {
|
| + const ActivationScopeTestData& test_data = GetParam();
|
| + scoped_configuration()->ResetConfiguration(
|
| + Configuration(ActivationLevel::ENABLED, test_data.activation_scope,
|
| + ActivationList::SUBRESOURCE_FILTER));
|
| +
|
| + const GURL test_url(kURLWithParams);
|
| + if (test_data.url_matches_activation_list)
|
| + ConfigureForMatch(test_url);
|
| + SimulateNavigateAndCommit({test_url}, main_rfh());
|
| + EXPECT_EQ(test_data.expected_activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + if (test_data.url_matches_activation_list) {
|
| + factory()->client()->WhitelistInCurrentWebContents(test_url);
|
| + ActivationDecision expected_decision =
|
| + test_data.expected_activation_decision;
|
| + if (expected_decision == ActivationDecision::ACTIVATED)
|
| + expected_decision = ActivationDecision::URL_WHITELISTED;
|
| + SimulateNavigateAndCommit({test_url}, main_rfh());
|
| + EXPECT_EQ(expected_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| +};
|
| +
|
| +// Only main frames with http/https schemes should activate.
|
| +TEST_P(SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
|
| + ActivateForSupportedUrlScheme) {
|
| + const ActivationScopeTestData& test_data = GetParam();
|
| + scoped_configuration()->ResetConfiguration(
|
| + Configuration(ActivationLevel::ENABLED, test_data.activation_scope,
|
| + ActivationList::SUBRESOURCE_FILTER));
|
| +
|
| + // data URLs are also not supported, but not listed here, as it's not possible
|
| + // for a page to redirect to them after https://crbug.com/594215 is fixed.
|
| + const char* unsupported_urls[] = {"ftp://example.com/", "chrome://settings",
|
| + "chrome-extension://some-extension",
|
| + "file:///var/www/index.html"};
|
| + const char* supported_urls[] = {"http://example.test",
|
| + "https://example.test"};
|
| + for (auto* url : unsupported_urls) {
|
| + SCOPED_TRACE(url);
|
| + if (test_data.url_matches_activation_list)
|
| + ConfigureForMatch(GURL(url));
|
| + SimulateNavigateAndCommit({GURL(url)}, main_rfh());
|
| + ActivationDecision expected_decision =
|
| + ActivationDecision::UNSUPPORTED_SCHEME;
|
| + // We only log UNSUPPORTED_SCHEME if the navigation would have otherwise
|
| + // activated. Note that non http/s URLs will never match an activation list.
|
| + if (test_data.expected_activation_decision ==
|
| + ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET ||
|
| + test_data.activation_scope == ActivationScope::ACTIVATION_LIST) {
|
| + expected_decision = ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET;
|
| + }
|
| + EXPECT_EQ(expected_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| +
|
| + for (auto* url : supported_urls) {
|
| + SCOPED_TRACE(url);
|
| + if (test_data.url_matches_activation_list)
|
| + ConfigureForMatch(GURL(url));
|
| + SimulateNavigateAndCommit({GURL(url)}, main_rfh());
|
| + EXPECT_EQ(test_data.expected_activation_decision,
|
| + factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| + }
|
| +};
|
| +
|
| TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| ListNotMatched_NoActivation) {
|
| const ActivationListTestData& test_data = GetParam();
|
| const GURL url(kURL);
|
| const std::string suffix(GetSuffixForList(test_data.activation_list_type));
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateCommitAndExpectProceed();
|
| EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| @@ -386,8 +848,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const ActivationListTestData& test_data = GetParam();
|
| const GURL url(kURL);
|
| ConfigureForMatchParam(url);
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateCommitAndExpectProceed();
|
| EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| factory()->GetActivationDecisionForLastCommittedPageLoad());
|
| @@ -403,8 +864,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const ActivationListTestData& test_data = GetParam();
|
| const GURL url(kURL);
|
| const std::string suffix(GetSuffixForList(test_data.activation_list_type));
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
|
| SimulateCommitAndExpectProceed();
|
| EXPECT_EQ(ActivationDecision::ACTIVATION_CONDITIONS_NOT_MET,
|
| @@ -422,8 +882,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const GURL url(kURL);
|
| const std::string suffix(GetSuffixForList(test_data.activation_list_type));
|
| ConfigureForMatchParam(GURL(kRedirectURL));
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateRedirectAndExpectProceed(GURL(kRedirectURL));
|
| SimulateCommitAndExpectProceed();
|
| EXPECT_EQ(ActivationDecision::ACTIVATED,
|
| @@ -440,8 +899,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const GURL url(kURL);
|
| const std::string suffix(GetSuffixForList(test_data.activation_list_type));
|
| SimulateTimeout();
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
|
|
| // Flush the pending tasks on the IO thread, so the delayed task surely gets
|
| // posted.
|
| @@ -468,8 +926,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const ActivationListTestData& test_data = GetParam();
|
| const GURL url(kURL);
|
| ConfigureForMatchParam(url);
|
| - CreateTestNavigationForMainFrame(url);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
|
|
| // Get the database result back before commit.
|
| RunUntilIdle();
|
| @@ -494,9 +951,8 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const GURL url(kURL);
|
| const GURL redirect_url(kRedirectURL);
|
| ConfigureForMatchParam(redirect_url);
|
| - CreateTestNavigationForMainFrame(url);
|
|
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateRedirectAndExpectProceed(redirect_url);
|
|
|
| // Get the database result back before commit.
|
| @@ -522,11 +978,10 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| const GURL url(kURL);
|
| const GURL redirect_url(kRedirectURL);
|
| ConfigureForMatchParam(url);
|
| - CreateTestNavigationForMainFrame(url);
|
|
|
| // These two lines also test how the database client reacts to two requests
|
| // happening one after another.
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(url);
|
| SimulateRedirectAndExpectProceed(redirect_url);
|
|
|
| // Get the database result back before commit.
|
| @@ -575,8 +1030,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| if (test_data.blacklisted_urls[i])
|
| ConfigureForMatchParam(test_data.navigation_chain[i]);
|
| }
|
| - CreateTestNavigationForMainFrame(*it);
|
| - SimulateStartAndExpectProceed();
|
| + SimulateStartAndExpectProceed(*it);
|
| for (++it; it != test_data.navigation_chain.end(); ++it)
|
| SimulateRedirectAndExpectProceed(*it);
|
| SimulateCommitAndExpectProceed();
|
| @@ -611,9 +1065,8 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
|
| SCOPED_TRACE(::testing::Message() << "CancelTime: " << cancel_time()
|
| << " ResultSynchrony: " << result_sync());
|
| ConfigureForMatch(url);
|
| - CreateTestNavigationForMainFrame(url);
|
| -
|
| - content::NavigationThrottle::ThrottleCheckResult result = SimulateStart();
|
| + content::NavigationThrottle::ThrottleCheckResult result =
|
| + SimulateStart(url, main_rfh());
|
| if (cancel_time() ==
|
| content::CancellingNavigationThrottle::WILL_START_REQUEST) {
|
| EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
|
| @@ -633,7 +1086,7 @@ TEST_P(SubresourceFilterSafeBrowsingActivationThrottleTestWithCancelling,
|
|
|
| base::RunLoop().RunUntilIdle();
|
|
|
| - result = SimulateCommit();
|
| + result = SimulateCommit(navigation_simulator());
|
| EXPECT_EQ(content::NavigationThrottle::CANCEL, result);
|
| tester().ExpectTotalCount(kSafeBrowsingNavigationDelay, 0);
|
| }
|
| @@ -655,4 +1108,9 @@ INSTANTIATE_TEST_CASE_P(
|
| SubresourceFilterSafeBrowsingActivationThrottleParamTest,
|
| ::testing::ValuesIn(kActivationListTestData));
|
|
|
| +INSTANTIATE_TEST_CASE_P(
|
| + ActivationScopeTest,
|
| + SubresourceFilterSafeBrowsingActivationThrottleScopeTest,
|
| + ::testing::ValuesIn(kActivationScopeTestData));
|
| +
|
| } // namespace subresource_filter
|
|
|