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