Commit 9cd171d2 authored by Daniel Rubery's avatar Daniel Rubery Committed by Commit Bot

Add browser test for matching the visual model and showing an interstitial

This CL removes an old browser test that wasn't being built or run, and
adds a browser test for the end-to-end process of loading a page that
matches the visual model, contacting Safe Browsing, and showing an
interstitial if Safe Browsing returns a dangerous verdict.

Fixed: 1104281
Change-Id: I3cba65bb101da6f68e7e9406e7183b6aae12743a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2296373Reviewed-by: default avatarBettina Dea <bdea@chromium.org>
Commit-Queue: Daniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/master@{#788682}
parent fa7a9f70
...@@ -575,16 +575,18 @@ void ClientSideDetectionHost::set_client_side_detection_service( ...@@ -575,16 +575,18 @@ void ClientSideDetectionHost::set_client_side_detection_service(
csd_service_ = service; csd_service_ = service;
} }
void ClientSideDetectionHost::set_safe_browsing_managers( void ClientSideDetectionHost::set_ui_manager(
SafeBrowsingUIManager* ui_manager, SafeBrowsingUIManager* ui_manager) {
SafeBrowsingDatabaseManager* database_manager) {
if (ui_manager_.get()) if (ui_manager_.get())
ui_manager_->RemoveObserver(this); ui_manager_->RemoveObserver(this);
ui_manager_ = ui_manager; ui_manager_ = ui_manager;
if (ui_manager) if (ui_manager)
ui_manager_->AddObserver(this); ui_manager_->AddObserver(this);
}
void ClientSideDetectionHost::set_database_manager(
SafeBrowsingDatabaseManager* database_manager) {
database_manager_ = database_manager; database_manager_ = database_manager;
} }
......
...@@ -70,14 +70,15 @@ class ClientSideDetectionHost : public content::WebContentsObserver, ...@@ -70,14 +70,15 @@ class ClientSideDetectionHost : public content::WebContentsObserver,
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
// Used for testing. // Used for testing.
void set_safe_browsing_managers( void set_ui_manager(SafeBrowsingUIManager* ui_manager);
SafeBrowsingUIManager* ui_manager, void set_database_manager(SafeBrowsingDatabaseManager* database_manager);
SafeBrowsingDatabaseManager* database_manager);
private: private:
friend class ClientSideDetectionHostTestBase; friend class ClientSideDetectionHostTestBase;
class ShouldClassifyUrlRequest; class ShouldClassifyUrlRequest;
friend class ShouldClassifyUrlRequest; friend class ShouldClassifyUrlRequest;
FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionHostBrowserTest,
VerifyVisualFeatureCollection);
// Called when pre-classification checks are done for the phishing // Called when pre-classification checks are done for the phishing
// classifiers. // classifiers.
......
...@@ -6,75 +6,138 @@ ...@@ -6,75 +6,138 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/client_side_detection_service.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/proto/client_model.pb.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h" #include "url/gurl.h"
using content::WebContents;
namespace safe_browsing { namespace safe_browsing {
namespace { namespace {
class TestClientSideDetectionHost : public ClientSideDetectionHost { using ::testing::_;
using ::testing::StrictMock;
class FakeClientSideDetectionService : public ClientSideDetectionService {
public: public:
explicit TestClientSideDetectionHost(WebContents* tab) FakeClientSideDetectionService() : ClientSideDetectionService(nullptr) {}
: ClientSideDetectionHost(tab) {}
private: void SendClientReportPhishingRequest(
void OnMalwarePreClassificationDone(bool should_classify_not_used) override { ClientPhishingRequest* verdict,
ClientSideDetectionHost::OnMalwarePreClassificationDone(true); bool is_extended_reporting,
bool is_enhanced_protection,
const ClientReportPhishingRequestCallback& callback) override {
saved_request_ = *verdict;
// TODO(drubery): This can be removed if SendClientReportPhishingRequest
// takes a unique_ptr<ClientPhishingRequest>, while also providing better
// guarantees about memory safety.
delete verdict;
saved_callback_ = callback;
request_callback_.Run();
}
const ClientPhishingRequest& saved_request() { return saved_request_; }
const ClientReportPhishingRequestCallback& saved_callback() {
return saved_callback_;
} }
void DidStopLoading() override {} void SetModel(const ClientSideModel& model) { model_ = model; }
std::string GetModelStr() override { return model_.SerializeAsString(); }
void SetRequestCallback(const base::RepeatingClosure& closure) {
request_callback_ = closure;
}
private:
ClientPhishingRequest saved_request_;
ClientReportPhishingRequestCallback saved_callback_;
ClientSideModel model_;
base::RepeatingClosure request_callback_;
}; };
bool FindExpectedIPUrlInfo(const IPUrlInfo& expected_info, class MockSafeBrowsingUIManager : public SafeBrowsingUIManager {
const std::vector<IPUrlInfo>& ip_url_vector) { public:
auto result = std::find_if( MockSafeBrowsingUIManager() : SafeBrowsingUIManager(nullptr) {}
ip_url_vector.begin(), ip_url_vector.end(),
[expected_info](const IPUrlInfo& ip_url_info) { MOCK_METHOD1(DisplayBlockingPage, void(const UnsafeResource& resource));
return expected_info.origin_of_final_url ==
ip_url_info.origin_of_final_url && protected:
expected_info.method == ip_url_info.method && ~MockSafeBrowsingUIManager() override = default;
expected_info.referrer == ip_url_info.referrer &&
expected_info.resource_type == ip_url_info.resource_type; private:
}); DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager);
return result != ip_url_vector.end(); };
}
} // namespace } // namespace
using ClientSideDetectionHostBrowserTest = InProcessBrowserTest; class ClientSideDetectionHostBrowserTest : public InProcessBrowserTest {
public:
ClientSideDetectionHostBrowserTest() = default;
~ClientSideDetectionHostBrowserTest() override = default;
};
IN_PROC_BROWSER_TEST_F(ClientSideDetectionHostBrowserTest, IN_PROC_BROWSER_TEST_F(ClientSideDetectionHostBrowserTest,
VerifyIPAddressCollection) { VerifyVisualFeatureCollection) {
browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled, FakeClientSideDetectionService fake_csd_service;
false);
ClientSideModel model;
model.set_version(123);
model.set_max_words_per_term(1);
VisualTarget* target = model.mutable_vision_model()->add_targets();
target->set_digest("target1_digest");
// Create a hash corresponding to a blank screen.
std::string hash = "\x30";
for (int i = 0; i < 288; i++)
hash += "\xff";
target->set_hash(hash);
target->set_dimension_size(48);
MatchRule* match_rule = target->mutable_match_config()->add_match_rule();
// The actual hash distance is 76, so set the distance to 100 for safety.
match_rule->set_hash_distance(100);
fake_csd_service.SetModel(model);
scoped_refptr<StrictMock<MockSafeBrowsingUIManager>> mock_ui_manager =
new StrictMock<MockSafeBrowsingUIManager>();
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
std::unique_ptr<TestClientSideDetectionHost> csd_host = std::unique_ptr<ClientSideDetectionHost> csd_host =
std::make_unique<TestClientSideDetectionHost>( ClientSideDetectionHost::Create(
browser()->tab_strip_model()->GetActiveWebContents()); browser()->tab_strip_model()->GetActiveWebContents());
csd_host->set_client_side_detection_service(&fake_csd_service);
csd_host->SendModelToRenderFrame();
csd_host->set_ui_manager(mock_ui_manager.get());
GURL page_url(embedded_test_server()->GetURL("/safe_browsing/malware.html")); GURL page_url(embedded_test_server()->GetURL("/safe_browsing/malware.html"));
ui_test_utils::NavigateToURL(browser(), page_url); ui_test_utils::NavigateToURL(browser(), page_url);
BrowseInfo* browse_info = csd_host->GetBrowseInfo(); base::RunLoop run_loop;
EXPECT_EQ(1u, browse_info->ips.size()); fake_csd_service.SetRequestCallback(run_loop.QuitClosure());
const std::vector<IPUrlInfo>& ip_urls =
browse_info->ips[embedded_test_server()->base_url().host()]; // Bypass the pre-classification checks
url::Origin expected_origin_of_final_url = csd_host->OnPhishingPreClassificationDone(/*should_classify=*/true);
url::Origin::Create(embedded_test_server()->GetURL("/"));
IPUrlInfo expected_result_1(expected_origin_of_final_url.Serialize(), "GET", run_loop.Run();
page_url.spec(),
blink::mojom::ResourceType::kImage); ASSERT_FALSE(fake_csd_service.saved_callback().is_null());
IPUrlInfo expected_result_2(expected_origin_of_final_url.Serialize(), "GET",
page_url.spec(), EXPECT_EQ(fake_csd_service.saved_request().model_version(), 123);
blink::mojom::ResourceType::kSubFrame); ASSERT_EQ(fake_csd_service.saved_request().vision_match_size(), 1);
EXPECT_TRUE(FindExpectedIPUrlInfo(expected_result_1, ip_urls)); EXPECT_EQ(
EXPECT_TRUE(FindExpectedIPUrlInfo(expected_result_2, ip_urls)); fake_csd_service.saved_request().vision_match(0).matched_target_digest(),
"target1_digest");
// Expect an interstitail to be shown
EXPECT_CALL(*mock_ui_manager, DisplayBlockingPage(_));
fake_csd_service.saved_callback().Run(page_url, true);
} }
} // namespace safe_browsing } // namespace safe_browsing
...@@ -295,8 +295,8 @@ class ClientSideDetectionHostTestBase : public ChromeRenderViewHostTestHarness { ...@@ -295,8 +295,8 @@ class ClientSideDetectionHostTestBase : public ChromeRenderViewHostTestHarness {
csd_host_ = ClientSideDetectionHost::Create(web_contents()); csd_host_ = ClientSideDetectionHost::Create(web_contents());
csd_host_->set_client_side_detection_service(csd_service_.get()); csd_host_->set_client_side_detection_service(csd_service_.get());
csd_host_->set_safe_browsing_managers(ui_manager_.get(), csd_host_->set_ui_manager(ui_manager_.get());
database_manager_.get()); csd_host_->set_database_manager(database_manager_.get());
csd_host_->set_tick_clock_for_testing(&clock_); csd_host_->set_tick_clock_for_testing(&clock_);
// We need to create this here since we don't call DidStopLanding in // We need to create this here since we don't call DidStopLanding in
......
...@@ -1129,6 +1129,7 @@ if (!is_android) { ...@@ -1129,6 +1129,7 @@ if (!is_android) {
"../browser/resource_coordinator/tab_activity_watcher_browsertest.cc", "../browser/resource_coordinator/tab_activity_watcher_browsertest.cc",
"../browser/resource_coordinator/tab_manager_browsertest.cc", "../browser/resource_coordinator/tab_manager_browsertest.cc",
"../browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc", "../browser/safe_browsing/chrome_cleaner/reporter_runner_browsertest_win.cc",
"../browser/safe_browsing/client_side_detection_host_browsertest.cc",
"../browser/safe_browsing/client_side_detection_service_browsertest.cc", "../browser/safe_browsing/client_side_detection_service_browsertest.cc",
"../browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc", "../browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.cc",
"../browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h", "../browser/safe_browsing/cloud_content_scanning/deep_scanning_browsertest_base.h",
......
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