1 // Copyright 2020 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/strings/string16.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "base/values.h"
8 #include "build/build_config.h"
9 #include "chrome/browser/apps/app_service/app_launch_params.h"
10 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
11 #include "chrome/browser/policy/policy_test_utils.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_commands.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "components/policy/core/common/policy_map.h"
17 #include "components/policy/core/common/policy_pref_names.h"
18 #include "components/policy/core/common/policy_types.h"
19 #include "components/policy/policy_constants.h"
20 #include "components/prefs/pref_service.h"
21 #include "content/public/test/browser_test.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "url/gurl.h"
26 
27 #if !defined(OS_MAC)
28 #include "extensions/browser/app_window/app_window.h"
29 #include "ui/base/window_open_disposition.h"
30 #endif
31 
32 using content::BrowserThread;
33 
34 namespace policy {
35 
36 namespace {
37 
38 // Verifies that the given url |spec| can be opened. This assumes that |spec|
39 // points at empty.html in the test data dir.
CheckCanOpenURL(Browser * browser,const std::string & spec)40 void CheckCanOpenURL(Browser* browser, const std::string& spec) {
41   GURL url(spec);
42   ui_test_utils::NavigateToURL(browser, url);
43   content::WebContents* contents =
44       browser->tab_strip_model()->GetActiveWebContents();
45   EXPECT_EQ(url, contents->GetURL());
46 
47   base::string16 blocked_page_title;
48   if (url.has_host()) {
49     blocked_page_title = base::UTF8ToUTF16(url.host());
50   } else {
51     // Local file paths show the full URL.
52     blocked_page_title = base::UTF8ToUTF16(url.spec());
53   }
54   EXPECT_NE(blocked_page_title, contents->GetTitle());
55 }
56 
57 }  //  namespace
58 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklist)59 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklist) {
60   // Checks that URLs can be blacklisted, and that exceptions can be made to
61   // the blacklist.
62 
63   ASSERT_TRUE(embedded_test_server()->Start());
64 
65   const std::string kURLS[] = {
66       embedded_test_server()->GetURL("aaa.com", "/empty.html").spec(),
67       embedded_test_server()->GetURL("bbb.com", "/empty.html").spec(),
68       embedded_test_server()->GetURL("sub.bbb.com", "/empty.html").spec(),
69       embedded_test_server()->GetURL("bbb.com", "/policy/blank.html").spec(),
70       embedded_test_server()->GetURL("bbb.com.", "/policy/blank.html").spec(),
71   };
72 
73   // Verify that "bbb.com" opens before applying the blacklist.
74   CheckCanOpenURL(browser(), kURLS[1]);
75 
76   // Set a blacklist.
77   base::ListValue blacklist;
78   blacklist.AppendString("bbb.com");
79   PolicyMap policies;
80   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
81                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
82   UpdateProviderPolicy(policies);
83   FlushBlacklistPolicy();
84   // All bbb.com URLs are blocked, and "aaa.com" is still unblocked.
85   CheckCanOpenURL(browser(), kURLS[0]);
86   for (size_t i = 1; i < base::size(kURLS); ++i)
87     CheckURLIsBlocked(browser(), kURLS[i]);
88 
89   // Whitelist some sites of bbb.com.
90   base::ListValue whitelist;
91   whitelist.AppendString("sub.bbb.com");
92   whitelist.AppendString("bbb.com/policy");
93   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
94                POLICY_SOURCE_CLOUD, whitelist.Clone(), nullptr);
95   UpdateProviderPolicy(policies);
96   FlushBlacklistPolicy();
97   CheckURLIsBlocked(browser(), kURLS[1]);
98   CheckCanOpenURL(browser(), kURLS[2]);
99   CheckCanOpenURL(browser(), kURLS[3]);
100   CheckCanOpenURL(browser(), kURLS[4]);
101 }
102 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklistIncognito)103 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistIncognito) {
104   // Checks that URLs can be blacklisted, and that exceptions can be made to
105   // the blacklist.
106 
107   Browser* incognito_browser =
108       OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
109 
110   ASSERT_TRUE(embedded_test_server()->Start());
111 
112   const std::string kURLS[] = {
113       embedded_test_server()->GetURL("aaa.com", "/empty.html").spec(),
114       embedded_test_server()->GetURL("bbb.com", "/empty.html").spec(),
115       embedded_test_server()->GetURL("sub.bbb.com", "/empty.html").spec(),
116       embedded_test_server()->GetURL("bbb.com", "/policy/blank.html").spec(),
117       embedded_test_server()->GetURL("bbb.com.", "/policy/blank.html").spec(),
118   };
119 
120   // Verify that "bbb.com" opens before applying the blacklist.
121   CheckCanOpenURL(incognito_browser, kURLS[1]);
122 
123   // Set a blacklist.
124   base::ListValue blacklist;
125   blacklist.AppendString("bbb.com");
126   PolicyMap policies;
127   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
128                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
129   UpdateProviderPolicy(policies);
130   FlushBlacklistPolicy();
131   // All bbb.com URLs are blocked, and "aaa.com" is still unblocked.
132   CheckCanOpenURL(incognito_browser, kURLS[0]);
133   for (size_t i = 1; i < base::size(kURLS); ++i)
134     CheckURLIsBlocked(incognito_browser, kURLS[i]);
135 
136   // Whitelist some sites of bbb.com.
137   base::ListValue whitelist;
138   whitelist.AppendString("sub.bbb.com");
139   whitelist.AppendString("bbb.com/policy");
140   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
141                POLICY_SOURCE_CLOUD, whitelist.Clone(), nullptr);
142   UpdateProviderPolicy(policies);
143   FlushBlacklistPolicy();
144   CheckURLIsBlocked(incognito_browser, kURLS[1]);
145   CheckCanOpenURL(incognito_browser, kURLS[2]);
146   CheckCanOpenURL(incognito_browser, kURLS[3]);
147   CheckCanOpenURL(incognito_browser, kURLS[4]);
148 }
149 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklistAndWhitelist)150 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistAndWhitelist) {
151   // Regression test for http://crbug.com/755256. Blacklisting * and
152   // whitelisting an origin should work.
153 
154   ASSERT_TRUE(embedded_test_server()->Start());
155 
156   base::ListValue blacklist;
157   blacklist.AppendString("*");
158   PolicyMap policies;
159   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
160                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
161 
162   base::ListValue whitelist;
163   whitelist.AppendString("aaa.com");
164   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
165                POLICY_SOURCE_CLOUD, whitelist.Clone(), nullptr);
166   UpdateProviderPolicy(policies);
167   FlushBlacklistPolicy();
168   CheckCanOpenURL(
169       browser(),
170       embedded_test_server()->GetURL("aaa.com", "/empty.html").spec());
171 }
172 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklistSubresources)173 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistSubresources) {
174   // Checks that an image with a blacklisted URL is loaded, but an iframe with a
175   // blacklisted URL is not.
176 
177   ASSERT_TRUE(embedded_test_server()->Start());
178 
179   GURL main_url =
180       embedded_test_server()->GetURL("/policy/blacklist-subresources.html");
181   GURL image_url = embedded_test_server()->GetURL("/policy/pixel.png");
182   GURL subframe_url = embedded_test_server()->GetURL("/policy/blank.html");
183 
184   // Set a blacklist containing the image and the iframe which are used by the
185   // main document.
186   base::ListValue blacklist;
187   blacklist.AppendString(image_url.spec().c_str());
188   blacklist.AppendString(subframe_url.spec().c_str());
189   PolicyMap policies;
190   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
191                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
192   UpdateProviderPolicy(policies);
193   FlushBlacklistPolicy();
194 
195   std::string blacklisted_image_load_result;
196   ui_test_utils::NavigateToURL(browser(), main_url);
197   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
198       browser()->tab_strip_model()->GetActiveWebContents(),
199       "window.domAutomationController.send(imageLoadResult)",
200       &blacklisted_image_load_result));
201   EXPECT_EQ("success", blacklisted_image_load_result);
202 
203   std::string blacklisted_iframe_load_result;
204   ui_test_utils::NavigateToURL(browser(), main_url);
205   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
206       browser()->tab_strip_model()->GetActiveWebContents(),
207       "window.domAutomationController.send(iframeLoadResult)",
208       &blacklisted_iframe_load_result));
209   EXPECT_EQ("error", blacklisted_iframe_load_result);
210 }
211 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklistClientRedirect)212 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistClientRedirect) {
213   // Checks that a client side redirect to a blacklisted URL is blocked.
214   ASSERT_TRUE(embedded_test_server()->Start());
215 
216   GURL redirected_url =
217       embedded_test_server()->GetURL("/policy/blacklist-redirect.html");
218   GURL first_url = embedded_test_server()->GetURL("/client-redirect?" +
219                                                   redirected_url.spec());
220 
221   // There are two navigations: one when loading client-redirect.html and
222   // another when the document redirects using http-equiv="refresh".
223   ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
224                                                             first_url, 2);
225   EXPECT_EQ(base::ASCIIToUTF16("Redirected!"),
226             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
227 
228   base::ListValue blacklist;
229   blacklist.AppendString(redirected_url.spec().c_str());
230   PolicyMap policies;
231   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
232                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
233   UpdateProviderPolicy(policies);
234   FlushBlacklistPolicy();
235 
236   ui_test_utils::NavigateToURL(browser(), first_url);
237   content::WaitForLoadStop(
238       browser()->tab_strip_model()->GetActiveWebContents());
239   EXPECT_NE(base::ASCIIToUTF16("Redirected!"),
240             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
241 }
242 
IN_PROC_BROWSER_TEST_F(PolicyTest,URLBlacklistServerRedirect)243 IN_PROC_BROWSER_TEST_F(PolicyTest, URLBlacklistServerRedirect) {
244   // Checks that a server side redirect to a blacklisted URL is blocked.
245   ASSERT_TRUE(embedded_test_server()->Start());
246 
247   GURL redirected_url =
248       embedded_test_server()->GetURL("/policy/blacklist-redirect.html");
249   GURL first_url = embedded_test_server()->GetURL("/server-redirect?" +
250                                                   redirected_url.spec());
251 
252   ui_test_utils::NavigateToURL(browser(), first_url);
253   content::WaitForLoadStop(
254       browser()->tab_strip_model()->GetActiveWebContents());
255   EXPECT_EQ(base::ASCIIToUTF16("Redirected!"),
256             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
257 
258   base::ListValue blacklist;
259   blacklist.AppendString(redirected_url.spec().c_str());
260   PolicyMap policies;
261   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
262                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
263   UpdateProviderPolicy(policies);
264   FlushBlacklistPolicy();
265 
266   ui_test_utils::NavigateToURL(browser(), first_url);
267   content::WaitForLoadStop(
268       browser()->tab_strip_model()->GetActiveWebContents());
269   EXPECT_NE(base::ASCIIToUTF16("Redirected!"),
270             browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
271 }
272 
273 #if defined(OS_MAC)
274 // http://crbug.com/339240
275 #define MAYBE_FileURLBlacklist DISABLED_FileURLBlacklist
276 #else
277 #define MAYBE_FileURLBlacklist FileURLBlacklist
278 #endif
IN_PROC_BROWSER_TEST_F(PolicyTest,MAYBE_FileURLBlacklist)279 IN_PROC_BROWSER_TEST_F(PolicyTest, MAYBE_FileURLBlacklist) {
280   // Check that FileURLs can be blacklisted and DisabledSchemes works together
281   // with URLblacklisting and URLwhitelisting.
282 
283   base::FilePath test_path;
284   GetTestDataDirectory(&test_path);
285   const std::string base_path = "file://" + test_path.AsUTF8Unsafe() + "/";
286   const std::string folder_path = base_path + "apptest/";
287   const std::string file_path1 = base_path + "title1.html";
288   const std::string file_path2 = folder_path + "basic.html";
289 
290   CheckCanOpenURL(browser(), file_path1);
291   CheckCanOpenURL(browser(), file_path2);
292 
293   // Set a blacklist for all the files.
294   base::ListValue blacklist;
295   blacklist.AppendString("file://*");
296   PolicyMap policies;
297   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
298                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
299   UpdateProviderPolicy(policies);
300   FlushBlacklistPolicy();
301 
302   CheckURLIsBlocked(browser(), file_path1);
303   CheckURLIsBlocked(browser(), file_path2);
304 
305   // Replace the URLblacklist with disabling the file scheme.
306   blacklist.Remove(base::Value("file://*"), nullptr);
307   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
308                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
309   UpdateProviderPolicy(policies);
310   FlushBlacklistPolicy();
311 
312   PrefService* prefs = browser()->profile()->GetPrefs();
313   const base::ListValue* list_url = prefs->GetList(policy_prefs::kUrlBlacklist);
314   EXPECT_EQ(list_url->Find(base::Value("file://*")), list_url->end());
315 
316   base::ListValue disabledscheme;
317   disabledscheme.AppendString("file");
318   policies.Set(key::kDisabledSchemes, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
319                POLICY_SOURCE_CLOUD, disabledscheme.Clone(), nullptr);
320   UpdateProviderPolicy(policies);
321   FlushBlacklistPolicy();
322 
323   list_url = prefs->GetList(policy_prefs::kUrlBlacklist);
324   EXPECT_NE(list_url->Find(base::Value("file://*")), list_url->end());
325 
326   // Whitelist one folder and blacklist an another just inside.
327   base::ListValue whitelist;
328   whitelist.AppendString(base_path);
329   policies.Set(key::kURLWhitelist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
330                POLICY_SOURCE_CLOUD, whitelist.Clone(), nullptr);
331   blacklist.AppendString(folder_path);
332   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
333                POLICY_SOURCE_CLOUD, blacklist.Clone(), nullptr);
334   UpdateProviderPolicy(policies);
335   FlushBlacklistPolicy();
336 
337   CheckCanOpenURL(browser(), file_path1);
338   CheckURLIsBlocked(browser(), file_path2);
339 }
340 
341 }  // namespace policy
342