1 // Copyright (c) 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/files/file_path.h"
6 #include "base/path_service.h"
7 #include "base/run_loop.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/common/chrome_paths.h"
11 #include "chrome/test/base/in_process_browser_test.h"
12 #include "chrome/test/base/ui_test_utils.h"
13 #include "components/safe_browsing/content/web_ui/safe_browsing_ui.h"
14 #include "components/safe_browsing/core/proto/csd.pb.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/download_manager.h"
17 #include "content/public/browser/site_instance.h"
18 #include "content/public/test/browser_test.h"
19 #include "content/public/test/download_test_observer.h"
20 #include "crypto/sha2.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/base/window_open_disposition.h"
23
24 namespace safe_browsing {
25
26 class DownloadProtectionServiceBrowserTest : public InProcessBrowserTest {
27 protected:
GetTestDataDirectory()28 base::FilePath GetTestDataDirectory() {
29 base::FilePath test_file_directory;
30 base::PathService::Get(chrome::DIR_TEST_DATA, &test_file_directory);
31 return test_file_directory;
32 }
33
DownloadAndWait(GURL url)34 void DownloadAndWait(GURL url) {
35 content::DownloadManager* download_manager =
36 content::BrowserContext::GetDownloadManager(browser()->profile());
37 content::DownloadTestObserverTerminal observer(
38 download_manager, 1,
39 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE);
40
41 // This call will block until the navigation completes, but will not wait
42 // for the download to finish.
43 ui_test_utils::NavigateToURLWithDisposition(
44 browser(), url, WindowOpenDisposition::CURRENT_TAB,
45 ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
46
47 observer.WaitForFinished();
48 }
49
50 // The hash of 10 A's, followed by a newline. Was generated as follows:
51 // echo "AAAAAAAAAA" > a.zip
52 // sha256sum a.zip
53 static const uint8_t kAZipDigest[];
54
55 // The hash of 9 B's, followed by a newline. Was generated as follows:
56 // echo "BBBBBBBBB" > a.zip
57 // sha256sum a.zip
58 static const uint8_t kBZipDigest[];
59 };
60
61 const uint8_t DownloadProtectionServiceBrowserTest::kAZipDigest[] = {
62 0x70, 0x5d, 0x29, 0x0c, 0x12, 0x89, 0x59, 0x01, 0xf8, 0x09, 0xf6,
63 0xc2, 0xfe, 0x77, 0x2a, 0x94, 0xdb, 0x51, 0x81, 0xd7, 0x26, 0x46,
64 0x4d, 0x84, 0x06, 0x82, 0x10, 0x6f, 0x4a, 0x93, 0x4b, 0x87};
65
66 const uint8_t DownloadProtectionServiceBrowserTest::kBZipDigest[] = {
67 0x94, 0x1e, 0x17, 0x3f, 0x62, 0xbc, 0x04, 0x50, 0x6f, 0xeb, 0xb5,
68 0xe2, 0x8c, 0x38, 0x6c, 0xb2, 0x11, 0x91, 0xf3, 0x77, 0xa7, 0x2c,
69 0x11, 0x92, 0xe0, 0x25, 0xb0, 0xe5, 0xc7, 0x70, 0x3b, 0x23};
70
IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,VerifyZipHash)71 IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest, VerifyZipHash) {
72 embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory());
73 ASSERT_TRUE(embedded_test_server()->Start());
74
75 WebUIInfoSingleton::GetInstance()->AddListenerForTesting();
76
77 GURL url = embedded_test_server()->GetURL(
78 "/safe_browsing/download_protection/zipfile_two_archives.zip");
79 DownloadAndWait(url);
80
81 const std::vector<std::unique_ptr<ClientDownloadRequest>>& requests =
82 WebUIInfoSingleton::GetInstance()->client_download_requests_sent();
83
84 ASSERT_EQ(1u, requests.size());
85 ASSERT_EQ(2, requests[0]->archived_binary_size());
86
87 EXPECT_EQ("a.zip", requests[0]->archived_binary(0).file_basename());
88 EXPECT_EQ(std::string(kAZipDigest, kAZipDigest + crypto::kSHA256Length),
89 requests[0]->archived_binary(0).digests().sha256());
90
91 EXPECT_EQ("b.zip", requests[0]->archived_binary(1).file_basename());
92 EXPECT_EQ(std::string(kBZipDigest, kBZipDigest + crypto::kSHA256Length),
93 requests[0]->archived_binary(1).digests().sha256());
94 }
95
IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,VerifyRarHash)96 IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest, VerifyRarHash) {
97 embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory());
98 ASSERT_TRUE(embedded_test_server()->Start());
99
100 WebUIInfoSingleton::GetInstance()->AddListenerForTesting();
101
102 GURL url =
103 embedded_test_server()->GetURL("/safe_browsing/rar/has_two_archives.rar");
104 DownloadAndWait(url);
105
106 const std::vector<std::unique_ptr<ClientDownloadRequest>>& requests =
107 WebUIInfoSingleton::GetInstance()->client_download_requests_sent();
108
109 ASSERT_EQ(1u, requests.size());
110 ASSERT_EQ(2, requests[0]->archived_binary_size());
111
112 EXPECT_EQ("a.zip", requests[0]->archived_binary(0).file_basename());
113 EXPECT_EQ(std::string(kAZipDigest, kAZipDigest + crypto::kSHA256Length),
114 requests[0]->archived_binary(0).digests().sha256());
115
116 EXPECT_EQ("b.zip", requests[0]->archived_binary(1).file_basename());
117 EXPECT_EQ(std::string(kBZipDigest, kBZipDigest + crypto::kSHA256Length),
118 requests[0]->archived_binary(1).digests().sha256());
119 }
120
IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,MultipartRarInspection)121 IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,
122 MultipartRarInspection) {
123 embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory());
124 ASSERT_TRUE(embedded_test_server()->Start());
125
126 WebUIInfoSingleton::GetInstance()->AddListenerForTesting();
127
128 GURL url = embedded_test_server()->GetURL(
129 "/safe_browsing/rar/multipart.part0001.rar");
130 DownloadAndWait(url);
131
132 const std::vector<std::unique_ptr<ClientDownloadRequest>>& requests =
133 WebUIInfoSingleton::GetInstance()->client_download_requests_sent();
134
135 ASSERT_EQ(1u, requests.size());
136 ASSERT_EQ(1, requests[0]->archived_binary_size());
137 EXPECT_EQ("random.exe", requests[0]->archived_binary(0).file_basename());
138 }
139
IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,MultipartRarInspectionSecondPart)140 IN_PROC_BROWSER_TEST_F(DownloadProtectionServiceBrowserTest,
141 MultipartRarInspectionSecondPart) {
142 embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory());
143 ASSERT_TRUE(embedded_test_server()->Start());
144
145 WebUIInfoSingleton::GetInstance()->AddListenerForTesting();
146
147 GURL url = embedded_test_server()->GetURL(
148 "/safe_browsing/rar/multipart.part0002.rar");
149 DownloadAndWait(url);
150
151 const std::vector<std::unique_ptr<ClientDownloadRequest>>& requests =
152 WebUIInfoSingleton::GetInstance()->client_download_requests_sent();
153
154 ASSERT_EQ(1u, requests.size());
155 ASSERT_EQ(1, requests[0]->archived_binary_size());
156 EXPECT_EQ("random.exe", requests[0]->archived_binary(0).file_basename());
157 }
158
159 } // namespace safe_browsing
160