Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Flash by default and allow enabling with CTP #116

Merged
merged 2 commits into from
May 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions browser/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ source_set("ui") {
"brave_browser_command_controller.h",
"brave_pages.cc",
"brave_pages.h",
"content_settings/brave_content_setting_bubble_model.cc",
"content_settings/brave_content_setting_bubble_model.h",
"toolbar/brave_app_menu_model.cc",
"toolbar/brave_app_menu_model.h",
"views/importer/brave_import_lock_dialog_view.cc",
Expand Down
65 changes: 65 additions & 0 deletions browser/ui/content_settings/brave_content_setting_bubble_model.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/browser/ui/content_settings/brave_content_setting_bubble_model.h"

#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/plugins/plugin_utils.h"
#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h"
#include "chrome/grit/generated_resources.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "ui/base/l10n/l10n_util.h"

BraveContentSettingPluginBubbleModel::BraveContentSettingPluginBubbleModel(
Delegate* delegate, content::WebContents* web_contents, Profile* profile)
: ContentSettingSimpleBubbleModel(delegate,
web_contents,
profile,
CONTENT_SETTINGS_TYPE_PLUGINS), profile_(profile) {
content_settings::SettingInfo info;
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile);
GURL url = web_contents->GetURL();
std::unique_ptr<base::Value> value =
map->GetWebsiteSetting(url, url, content_type(), std::string(), &info);
// If the setting is not managed by the user, hide the "Manage" button.
if (info.source != content_settings::SETTING_SOURCE_USER)
set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone);
set_custom_link(l10n_util::GetStringUTF16(IDS_BLOCKED_PLUGINS_LOAD_ALL));
set_custom_link_enabled(
web_contents &&
TabSpecificContentSettings::FromWebContents(web_contents)
->load_plugins_link_enabled());
set_show_learn_more(true);
}

void BraveContentSettingPluginBubbleModel::OnLearnMoreClicked() {
if (delegate())
delegate()->ShowLearnMorePage(CONTENT_SETTINGS_TYPE_PLUGINS);
}

void BraveContentSettingPluginBubbleModel::OnCustomLinkClicked() {
RunPluginsOnPage();
}

void BraveContentSettingPluginBubbleModel::RunPluginsOnPage() {
// Web contents can be NULL if the tab was closed while the plugins
// settings bubble is visible.
if (!web_contents())
return;

HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile_);
map->SetContentSettingDefaultScope(
web_contents()->GetURL(),
GURL(),
CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(),
CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);

ChromeSubresourceFilterClient::FromWebContents(web_contents())
->OnReloadRequested();
}
23 changes: 23 additions & 0 deletions browser/ui/content_settings/brave_content_setting_bubble_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"

class Profile;

class BraveContentSettingPluginBubbleModel : public ContentSettingSimpleBubbleModel {
public:
BraveContentSettingPluginBubbleModel(Delegate* delegate,
content::WebContents* web_contents,
Profile* profile);

private:
void OnLearnMoreClicked() override;
void OnCustomLinkClicked() override;

void RunPluginsOnPage();
Profile* profile_;

DISALLOW_COPY_AND_ASSIGN(BraveContentSettingPluginBubbleModel);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ BraveHostContentSettingsMap::BraveHostContentSettingsMap(
InitializeReferrerContentSetting();
InitializeCookieContentSetting();
InitializeBraveShieldsContentSetting();
InitializeFlashContentSetting();
}

BraveHostContentSettingsMap::~BraveHostContentSettingsMap() {
Expand Down Expand Up @@ -60,3 +61,14 @@ void BraveHostContentSettingsMap::InitializeBraveShieldsContentSetting() {
brave_shields::kBraveShields,
CONTENT_SETTING_ALLOW);
}

void BraveHostContentSettingsMap::InitializeFlashContentSetting() {
SetContentSettingCustomScope(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_PLUGINS,
// One would think this should be brave_shields::kFlash; however, if you
// use it, it will always ask and click-to-play will not work.
std::string(),
CONTENT_SETTING_BLOCK);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BraveHostContentSettingsMap : public HostContentSettingsMap {
void InitializeReferrerContentSetting();
void InitializeCookieContentSetting();
void InitializeBraveShieldsContentSetting();
void InitializeFlashContentSetting();
~BraveHostContentSettingsMap() override;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index 0e1bec53e5c64024528e949d8a7a51e3877f3056..e99590efc9a2c0850e4958a76bccda53a2a09a36 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -15,6 +15,7 @@
#include "base/metrics/user_metrics.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "brave/browser/ui/content_settings/brave_content_setting_bubble_model.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/chrome_content_settings_utils.h"
@@ -1712,7 +1713,7 @@ ContentSettingBubbleModel*
profile, content_type);
}
if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS) {
- return new ContentSettingPluginBubbleModel(delegate, web_contents, profile);
+ return new BraveContentSettingPluginBubbleModel(delegate, web_contents, profile);
}
if (content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT) {
return new ContentSettingMixedScriptBubbleModel(delegate, web_contents,
199 changes: 199 additions & 0 deletions renderer/brave_content_settings_observer_flash_browsertest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "base/path_service.h"
#include "brave/browser/brave_content_browser_client.h"
#include "brave/common/brave_paths.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/ppapi_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "net/dns/mock_host_resolver.h"

const char kFlashPluginExists[] =
"domAutomationController.send(Array.from(navigator.plugins).filter("
" x => Array.from(x).some("
" y => y.type === 'application/x-shockwave-flash')).length)";

namespace {

class PageReloadWaiter {
public:
explicit PageReloadWaiter(content::WebContents* web_contents)
: web_contents_(web_contents),
navigation_observer_(web_contents,
web_contents->GetLastCommittedURL()) {}

bool Wait() {
navigation_observer_.WaitForNavigationFinished();
return content::WaitForLoadStop(web_contents_);
}

private:
content::WebContents* web_contents_;
content::TestNavigationManager navigation_observer_;
};

} // namespace

class BraveContentSettingsObserverFlashBrowserTest : public InProcessBrowserTest {
public:
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();

content_client_.reset(new ChromeContentClient);
content::SetContentClient(content_client_.get());
browser_content_client_.reset(new BraveContentBrowserClient());
content::SetBrowserClientForTesting(browser_content_client_.get());

host_resolver()->AddRule("*", "127.0.0.1");
content::SetupCrossSiteRedirector(embedded_test_server());

brave::RegisterPathProvider();
base::FilePath test_data_dir;
PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);

ASSERT_TRUE(embedded_test_server()->Start());

url_ = embedded_test_server()->GetURL("a.com", "/flash.html");
top_level_page_pattern_ =
ContentSettingsPattern::FromString("http://a.com/*");
}

void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
ASSERT_TRUE(ppapi::RegisterFlashTestPlugin(command_line));
// These tests are for the permission prompt to add and remove Flash from
// navigator.plugins. We disable Plugin Power Saver, because its plugin
// throttling make it harder to test if Flash was succcessfully enabled.
command_line->AppendSwitchASCII(
switches::kOverridePluginPowerSaverForTesting, "never");
}

void TearDown() override {
browser_content_client_.reset();
content_client_.reset();
}

const GURL& url() { return url_; }

const ContentSettingsPattern& top_level_page_pattern() {
return top_level_page_pattern_;
}

const ContentSettingsPattern& empty_pattern() {
return empty_pattern_;
}

HostContentSettingsMap * content_settings() {
return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
}

void UnblockFlash() {
content_settings()->SetContentSettingCustomScope(
top_level_page_pattern_,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(),
CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
}

void AllowFlash() {
content_settings()->SetContentSettingCustomScope(
top_level_page_pattern_,
ContentSettingsPattern::Wildcard(),
CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(),
CONTENT_SETTING_ALLOW);
}

content::WebContents* contents() {
return browser()->tab_strip_model()->GetActiveWebContents();
}

bool NavigateToURLUntilLoadStop(const GURL& url) {
ui_test_utils::NavigateToURL(browser(), url);
return WaitForLoadStop(contents());
}

private:
GURL url_;
ContentSettingsPattern top_level_page_pattern_;
ContentSettingsPattern empty_pattern_;
std::unique_ptr<ChromeContentClient> content_client_;
std::unique_ptr<BraveContentBrowserClient> browser_content_client_;

base::ScopedTempDir temp_user_data_dir_;
};

// Flash is blocked by default
IN_PROC_BROWSER_TEST_F(BraveContentSettingsObserverFlashBrowserTest,
BlockFlashByDefault) {
NavigateToURLUntilLoadStop(url());
int len;
ASSERT_TRUE(ExecuteScriptAndExtractInt(contents(),
kFlashPluginExists, &len));
ASSERT_EQ(len, 0);
}

// Flash is unblocked and click to play eventually allows
IN_PROC_BROWSER_TEST_F(BraveContentSettingsObserverFlashBrowserTest,
UnblockFlash) {
UnblockFlash();
NavigateToURLUntilLoadStop(url());
int len;
ASSERT_TRUE(ExecuteScriptAndExtractInt(contents(),
kFlashPluginExists, &len));
ASSERT_EQ(len, 0);

PermissionRequestManager* manager = PermissionRequestManager::FromWebContents(
contents());

auto popup_prompt_factory =
std::make_unique<MockPermissionPromptFactory>(manager);

EXPECT_EQ(0, popup_prompt_factory->TotalRequestCount());
popup_prompt_factory->set_response_type(PermissionRequestManager::ACCEPT_ALL);

PageReloadWaiter reload_waiter(contents());

bool value;
EXPECT_TRUE(ExecuteScriptAndExtractBool(contents(), "triggerPrompt();",
&value));
EXPECT_TRUE(value);
EXPECT_TRUE(reload_waiter.Wait());

EXPECT_EQ(1, popup_prompt_factory->TotalRequestCount());

// Shut down the popup window tab, as the normal test teardown assumes there
// is only one test tab.
popup_prompt_factory.reset();

ASSERT_TRUE(ExecuteScriptAndExtractInt(contents(),
kFlashPluginExists, &len));
ASSERT_GT(len, 0);
}

// Flash is explicitly allowed
IN_PROC_BROWSER_TEST_F(BraveContentSettingsObserverFlashBrowserTest,
AllowFlashExplicitAllows) {
AllowFlash();
NavigateToURLUntilLoadStop(url());
int len;
ASSERT_TRUE(ExecuteScriptAndExtractInt(contents(),
kFlashPluginExists, &len));
ASSERT_GT(len, 0);
}

6 changes: 6 additions & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ test("brave_browser_tests") {
"//brave/components/brave_shields/browser/tracking_protection_service_browsertest.cc",
"//brave/extensions/browser/brave_extension_provider_browsertest.cc",
"//brave/renderer/brave_content_settings_observer_browsertest.cc",
"//brave/renderer/brave_content_settings_observer_flash_browsertest.cc",
"//chrome/browser/extensions/browsertest_util.cc",
"//chrome/browser/extensions/browsertest_util.h",
"//chrome/browser/extensions/extension_browsertest.cc",
Expand All @@ -90,6 +91,11 @@ test("brave_browser_tests") {
deps = [
"//chrome/browser/ui",
"//chrome/test:browser_tests_runner",
"//ppapi/features",
":brave_browser_tests_deps",
]
data_deps = [
"//ppapi:ppapi_tests",
"//ppapi:power_saver_test_plugin",
]
}
22 changes: 22 additions & 0 deletions test/data/flash.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<script>
function triggerPrompt() {
document.getElementById('flash-link').click();
window.domAutomationController.send(true);
}
</script>
</head>
<body>
<object id="flash-object" data="test.swf"
type="application/x-shockwave-flash" width="400" height="100">
Flash not supported.
<br>
<a href="https://get.adobe.com/flashplayer/" id="flash-link">
Download Flash.
</a>
</object>
</body>
</html>