Include plus.google.com and plus.sandbox.google.com in the NaCl whitelist.
[chromium-blink-merge.git] / chrome / renderer / chrome_content_renderer_client_unittest.cc
blobe2b70d296e47a52c73c3c60b74b859e3b8b48479
1 // Copyright (c) 2012 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.
5 #include "chrome/renderer/chrome_content_renderer_client.h"
7 #include <vector>
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/renderer/searchbox/search_bouncer.h"
11 #include "content/public/common/webplugininfo.h"
12 #include "extensions/common/extension.h"
13 #include "extensions/common/extension_builder.h"
14 #include "extensions/common/manifest_constants.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/platform/WebVector.h"
18 #include "third_party/WebKit/public/web/WebPluginParams.h"
19 #include "url/gurl.h"
21 using blink::WebPluginParams;
22 using blink::WebString;
23 using blink::WebVector;
24 using content::WebPluginInfo;
25 using content::WebPluginMimeType;
27 namespace {
28 const bool kNaClRestricted = false;
29 const bool kNaClUnrestricted = true;
30 const bool kExtensionRestricted = false;
31 const bool kExtensionUnrestricted = true;
32 const bool kExtensionNotFromWebStore = false;
33 const bool kExtensionFromWebStore = true;
34 const bool kNotHostedApp = false;
35 const bool kHostedApp = true;
37 const char kExtensionUrl[] = "chrome-extension://extension_id/background.html";
39 const char kPhotosAppURL1[] = "https://foo.plus.google.com";
40 const char kPhotosAppURL2[] = "https://foo.plus.sandbox.google.com";
41 const char kPhotosManifestURL1[] = "https://ssl.gstatic.com/s2/oz/nacl/foo";
42 const char kPhotosManifestURL2[] = "https://ssl.gstatic.com/photos/nacl/foo";
44 const char kChatAppURL1[] = "https://foo.talkgadget.google.com/hangouts/foo";
45 const char kChatAppURL2[] = "https://foo.plus.google.com/hangouts/foo";
46 const char kChatAppURL3[] = "https://foo.plus.sandbox.google.com/hangouts/foo";
47 const char kChatManifestFS1[] =
48 "filesystem:https://foo.talkgadget.google.com/foo";
49 const char kChatManifestFS2[] = "filesystem:https://foo.plus.google.com/foo";
50 const char kChatManifestFS3[] =
51 "filesystem:https://foo.plus.sandbox.google.com/foo";
53 bool AllowsDevInterfaces(const WebPluginParams& params) {
54 for (size_t i = 0; i < params.attributeNames.size(); ++i) {
55 if (params.attributeNames[i] == WebString::fromUTF8("@dev"))
56 return true;
58 return false;
61 void AddFakeDevAttribute(WebPluginParams* params) {
62 WebVector<WebString> names(static_cast<size_t>(1));
63 WebVector<WebString> values(static_cast<size_t>(1));
64 names[0] = WebString::fromUTF8("@dev");
65 values[0] = WebString();
66 params->attributeNames.swap(names);
67 params->attributeValues.swap(values);
70 void AddContentTypeHandler(content::WebPluginInfo* info,
71 const char* mime_type,
72 const char* manifest_url) {
73 content::WebPluginMimeType mime_type_info;
74 mime_type_info.mime_type = mime_type;
75 mime_type_info.additional_param_names.push_back(UTF8ToUTF16("nacl"));
76 mime_type_info.additional_param_values.push_back(
77 UTF8ToUTF16(manifest_url));
78 info->mime_types.push_back(mime_type_info);
80 } // namespace
82 typedef testing::Test ChromeContentRendererClientTest;
85 scoped_refptr<const extensions::Extension> CreateTestExtension(
86 bool is_unrestricted, bool is_from_webstore, bool is_hosted_app,
87 const std::string& app_url) {
88 extensions::Manifest::Location location = is_unrestricted ?
89 extensions::Manifest::UNPACKED :
90 extensions::Manifest::INTERNAL;
91 int flags = is_from_webstore ?
92 extensions::Extension::FROM_WEBSTORE:
93 extensions::Extension::NO_FLAGS;
95 base::DictionaryValue manifest;
96 manifest.SetString("name", "NaCl Extension");
97 manifest.SetString("version", "1");
98 manifest.SetInteger("manifest_version", 2);
99 if (is_hosted_app) {
100 base::ListValue* url_list = new base::ListValue();
101 url_list->Append(base::Value::CreateStringValue(app_url));
102 manifest.Set(extensions::manifest_keys::kWebURLs, url_list);
103 manifest.SetString(extensions::manifest_keys::kLaunchWebURL, app_url);
105 std::string error;
106 return extensions::Extension::Create(base::FilePath(), location, manifest,
107 flags, &error);
110 scoped_refptr<const extensions::Extension> CreateExtension(
111 bool is_unrestricted, bool is_from_webstore) {
112 return CreateTestExtension(
113 is_unrestricted, is_from_webstore, kNotHostedApp, std::string());
116 scoped_refptr<const extensions::Extension> CreateHostedApp(
117 bool is_unrestricted, bool is_from_webstore, const std::string& app_url) {
118 return CreateTestExtension(is_unrestricted, is_from_webstore, kHostedApp,
119 app_url);
122 TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
123 // Unknown content types have no NaCl module.
125 WebPluginInfo info;
126 EXPECT_EQ(GURL(),
127 ChromeContentRendererClient::GetNaClContentHandlerURL(
128 "application/x-foo", info));
130 // Known content types have a NaCl module.
132 WebPluginInfo info;
133 AddContentTypeHandler(&info, "application/x-foo", "www.foo.com");
134 EXPECT_EQ(GURL("www.foo.com"),
135 ChromeContentRendererClient::GetNaClContentHandlerURL(
136 "application/x-foo", info));
138 // --enable-nacl allows all NaCl apps, with 'dev' interfaces.
140 WebPluginParams params;
141 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
142 GURL(),
143 GURL(),
144 kNaClUnrestricted,
145 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
146 &params));
147 EXPECT_TRUE(AllowsDevInterfaces(params));
149 // Unrestricted extensions are allowed without --enable-nacl, with 'dev'
150 // interfaces if called from an extension url.
152 WebPluginParams params;
153 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
154 GURL(),
155 GURL(kExtensionUrl),
156 kNaClRestricted,
157 CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
158 .get(),
159 &params));
160 EXPECT_TRUE(AllowsDevInterfaces(params));
162 // CWS extensions are allowed without --enable-nacl, without 'dev'
163 // interfaces if called from an extension url.
165 WebPluginParams params;
166 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
167 GURL(),
168 GURL(kExtensionUrl),
169 kNaClRestricted,
170 CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
171 &params));
172 EXPECT_FALSE(AllowsDevInterfaces(params));
174 // CWS extensions can't get 'dev' interfaces with --enable-nacl.
176 WebPluginParams params;
177 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
178 GURL(),
179 GURL(kExtensionUrl),
180 kNaClUnrestricted,
181 CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
182 &params));
183 EXPECT_FALSE(AllowsDevInterfaces(params));
185 // CWS extensions can't get 'dev' interfaces by injecting a fake
186 // '@dev' attribute.
188 WebPluginParams params;
189 AddFakeDevAttribute(&params);
190 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
191 GURL(),
192 GURL(kExtensionUrl),
193 kNaClRestricted,
194 CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
195 &params));
196 EXPECT_FALSE(AllowsDevInterfaces(params));
198 // The NaCl PDF extension is allowed without --enable-nacl, with 'dev'
199 // interfaces, from all URLs.
201 WebPluginParams params;
202 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
203 GURL("chrome-extension://acadkphlmlegjaadjagenfimbpphcgnh"),
204 GURL(),
205 kNaClRestricted,
206 CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
207 &params));
208 EXPECT_TRUE(AllowsDevInterfaces(params));
210 // Whitelisted URLs are allowed without --enable-nacl, without 'dev'
211 // interfaces. There is a whitelist for the app URL and the manifest URL.
213 WebPluginParams params;
214 // Whitelisted Photos app is allowed (two app URLs, two manifest URLs)
215 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
216 GURL(kPhotosManifestURL1),
217 GURL(kPhotosAppURL1),
218 kNaClRestricted,
219 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
220 &params));
221 EXPECT_FALSE(AllowsDevInterfaces(params));
222 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
223 GURL(kPhotosManifestURL1),
224 GURL(kPhotosAppURL2),
225 kNaClRestricted,
226 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
227 &params));
228 EXPECT_FALSE(AllowsDevInterfaces(params));
229 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
230 GURL(kPhotosManifestURL2),
231 GURL(kPhotosAppURL1),
232 kNaClRestricted,
233 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
234 &params));
235 EXPECT_FALSE(AllowsDevInterfaces(params));
236 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
237 GURL(kPhotosManifestURL2),
238 GURL(kPhotosAppURL2),
239 kNaClRestricted,
240 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
241 &params));
242 EXPECT_FALSE(AllowsDevInterfaces(params));
243 // Whitelisted Chat app is allowed.
244 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
245 GURL(kChatManifestFS1),
246 GURL(kChatAppURL1),
247 kNaClRestricted,
248 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
249 &params));
250 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
251 GURL(kChatManifestFS2),
252 GURL(kChatAppURL2),
253 kNaClRestricted,
254 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
255 &params));
256 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
257 GURL(kChatManifestFS3),
258 GURL(kChatAppURL3),
259 kNaClRestricted,
260 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
261 &params));
263 // Whitelisted manifest URL, bad app URLs, NOT allowed.
264 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
265 GURL(kPhotosManifestURL1),
266 GURL("http://plus.google.com/foo"), // http scheme
267 kNaClRestricted,
268 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
269 &params));
270 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
271 GURL(kPhotosManifestURL1),
272 GURL("http://plus.sandbox.google.com/foo"), // http scheme
273 kNaClRestricted,
274 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
275 &params));
276 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
277 GURL(kPhotosManifestURL1),
278 GURL("https://plus.google.evil.com/foo"), // bad host
279 kNaClRestricted,
280 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
281 &params));
282 // Whitelisted app URL, bad manifest URL, NOT allowed.
283 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
284 GURL("http://ssl.gstatic.com/s2/oz/nacl/foo"), // http scheme
285 GURL(kPhotosAppURL1),
286 kNaClRestricted,
287 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
288 &params));
289 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
290 GURL("https://ssl.gstatic.evil.com/s2/oz/nacl/foo"), // bad host
291 GURL(kPhotosAppURL1),
292 kNaClRestricted,
293 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
294 &params));
295 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
296 GURL("https://ssl.gstatic.com/wrong/s2/oz/nacl/foo"), // bad path
297 GURL(kPhotosAppURL1),
298 kNaClRestricted,
299 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
300 &params));
302 // Whitelisted URLs can't get 'dev' interfaces with --enable-nacl.
304 WebPluginParams params;
305 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
306 GURL(kPhotosManifestURL1),
307 GURL(kPhotosAppURL1),
308 kNaClUnrestricted,
309 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
310 &params));
311 EXPECT_FALSE(AllowsDevInterfaces(params));
313 // Whitelisted URLs can't get 'dev' interfaces by injecting a fake
314 // '@dev' attribute.
316 WebPluginParams params;
317 AddFakeDevAttribute(&params);
318 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
319 GURL(kPhotosManifestURL1),
320 GURL(kPhotosAppURL1),
321 kNaClRestricted,
322 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
323 &params));
324 EXPECT_FALSE(AllowsDevInterfaces(params));
326 // Non-whitelisted URLs are blocked without --enable-nacl.
328 WebPluginParams params;
329 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
330 GURL(),
331 GURL("https://plus.google.com.evil.com/foo1"),
332 kNaClRestricted,
333 CreateExtension(kExtensionRestricted, kExtensionNotFromWebStore).get(),
334 &params));
335 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
336 GURL(),
337 GURL("https://plus.google.com.evil.com/foo2"),
338 kNaClRestricted,
339 CreateExtension(kExtensionRestricted, kExtensionFromWebStore).get(),
340 &params));
341 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
342 GURL(),
343 GURL("https://talkgadget.google.com.evil.com/foo3"),
344 kNaClRestricted,
345 CreateExtension(kExtensionUnrestricted, kExtensionNotFromWebStore)
346 .get(),
347 &params));
348 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
349 GURL(),
350 GURL("https://talkgadget.google.com.evil.com/foo4"),
351 kNaClRestricted,
352 CreateExtension(kExtensionUnrestricted, kExtensionFromWebStore).get(),
353 &params));
355 // Non chrome-extension:// URLs belonging to hosted apps are allowed.
357 WebPluginParams params;
358 EXPECT_TRUE(ChromeContentRendererClient::IsNaClAllowed(
359 GURL(),
360 GURL("http://example.com/test.html"),
361 kNaClRestricted,
362 CreateHostedApp(kExtensionRestricted,
363 kExtensionNotFromWebStore,
364 "http://example.com/").get(),
365 &params));
366 EXPECT_FALSE(ChromeContentRendererClient::IsNaClAllowed(
367 GURL(),
368 GURL("http://example.evil.com/test.html"),
369 kNaClRestricted,
370 CreateHostedApp(kExtensionRestricted,
371 kExtensionNotFromWebStore,
372 "http://example.com/").get(),
373 &params));
377 TEST_F(ChromeContentRendererClientTest, AllowPepperMediaStreamAPI) {
378 ChromeContentRendererClient test;
379 #if !defined(OS_ANDROID)
380 EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
381 EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
382 EXPECT_TRUE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL3)));
383 #else
384 EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL1)));
385 EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL2)));
386 EXPECT_FALSE(test.AllowPepperMediaStreamAPI(GURL(kChatAppURL3)));
387 #endif
388 EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
389 GURL("http://talkgadget.google.com/hangouts/foo")));
390 EXPECT_FALSE(test.AllowPepperMediaStreamAPI(
391 GURL("https://talkgadget.evil.com/hangouts/foo")));
394 TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {
395 ChromeContentRendererClient client;
396 client.search_bouncer_.reset(new SearchBouncer);
397 client.search_bouncer_->OnSetSearchURLs(
398 std::vector<GURL>(), GURL("http://example.com/n"));
399 EXPECT_FALSE(client.ShouldSuppressErrorPage(GURL("http://example.com")));
400 EXPECT_TRUE(client.ShouldSuppressErrorPage(GURL("http://example.com/n")));