Commit 715c16f6 authored by Tommy Li's avatar Tommy Li Committed by Commit Bot

[flash] Delete FlashDownloadInterception

This CL deletes the mechanism to intercept attempts to download Adobe
Flash at get.adobe.com/flashplayer. This was previously used to issue
permission requests.

We're deleting this now.

Note this also disables changing of the Flash permission via permission
popup. We don't need that anymore either.

Bug: 1069832
Change-Id: I2c08625cff7648bdc353c1a15100f170ff86db00
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2458506Reviewed-by: default avatarRaymes Khoury <raymes@chromium.org>
Commit-Queue: Tommy Li <tommycli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814902}
parent 09aa4b94
......@@ -5764,8 +5764,6 @@ static_library("browser") {
"plugins/chrome_plugin_service_filter.h",
"plugins/flash_deprecation_infobar_delegate.cc",
"plugins/flash_deprecation_infobar_delegate.h",
"plugins/flash_download_interception.cc",
"plugins/flash_download_interception.h",
"plugins/flash_permission_context.cc",
"plugins/flash_permission_context.h",
"plugins/flash_temporary_permission_tracker.cc",
......
......@@ -573,7 +573,6 @@
#if BUILDFLAG(ENABLE_PLUGINS)
#include "chrome/browser/plugins/chrome_content_browser_client_plugins_part.h"
#include "chrome/browser/plugins/flash_download_interception.h"
#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h"
#endif
......@@ -3117,18 +3116,6 @@ bool ChromeContentBrowserClient::CanCreateWindow(
}
#endif
#if BUILDFLAG(ENABLE_PLUGINS)
HostContentSettingsMap* content_settings =
HostContentSettingsMapFactory::GetForProfile(profile);
if (FlashDownloadInterception::ShouldStopFlashDownloadAction(
content_settings, opener_top_level_frame_url, target_url,
user_gesture)) {
FlashDownloadInterception::InterceptFlashDownloadNavigation(
web_contents, opener_top_level_frame_url);
return false;
}
#endif
DCHECK(!prerender::ChromePrerenderContentsDelegate::FromWebContents(
web_contents));
......@@ -3903,11 +3890,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
page_load_metrics::MetricsNavigationThrottle::Create(handle));
}
#if BUILDFLAG(ENABLE_PLUGINS)
MaybeAddThrottle(FlashDownloadInterception::MaybeCreateThrottleFor(handle),
&throttles);
#endif
#if defined(OS_CHROMEOS)
MaybeAddThrottle(
chromeos::WebTimeLimitNavigationThrottle::MaybeCreateThrottleFor(handle),
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/plugins/flash_download_interception.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/no_destructor.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/browser/plugins/plugin_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_features.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/navigation_interception/intercept_navigation_throttle.h"
#include "components/navigation_interception/navigation_params.h"
#include "components/permissions/permission_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
#include "third_party/re2/src/re2/re2.h"
#include "url/origin.h"
using content::BrowserThread;
using content::NavigationHandle;
using content::NavigationThrottle;
namespace {
const RE2& GetFlashURLCanonicalRegex() {
static const base::NoDestructor<RE2> re("(?i)get2?\\.adobe\\.com/.*flash.*");
return *re;
}
const RE2& GetFlashURLSecondaryGoRegex() {
static const base::NoDestructor<RE2> re(
"(?i)(www\\.)?(adobe|macromedia)\\.com/go/"
"((?i).*get[-_]?flash|getfp10android|.*fl(ash)player|.*flashpl|"
".*flash_player|flash_completion|flashpm|.*flashdownload|d65_flplayer|"
"fp_jp|runtimes_fp|[a-z_-]{3,6}h-m-a-?2|chrome|download_player|"
"gnav_fl|pdcredirect).*");
return *re;
}
const RE2& GetFlashURLSecondaryDownloadRegex() {
static const base::NoDestructor<RE2> re(
"(?i)(www\\.)?(adobe|macromedia)\\.com/shockwave/download/download.cgi");
return *re;
}
const char kGetFlashURLSecondaryDownloadQuery[] =
"P1_Prod_Version=ShockwaveFlash";
bool InterceptNavigation(
const GURL& source_url,
content::WebContents* source,
const navigation_interception::NavigationParams& params) {
FlashDownloadInterception::InterceptFlashDownloadNavigation(source,
source_url);
return true;
}
} // namespace
// static
void FlashDownloadInterception::InterceptFlashDownloadNavigation(
content::WebContents* web_contents,
const GURL& source_url) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(profile);
ContentSetting flash_setting = PluginUtils::GetFlashPluginContentSetting(
host_content_settings_map, url::Origin::Create(source_url), source_url,
nullptr);
if (flash_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT) {
permissions::PermissionManager* manager =
PermissionManagerFactory::GetForProfile(profile);
// TODO(https://crbug.com/1103176): Plumb the actual frame reference here
// (FlashDownloadInterception is created only for renderer-initiated
// navigations, so we always should have a reference to the originating
// RenderFrameHost)
manager->RequestPermission(
ContentSettingsType::PLUGINS, web_contents->GetMainFrame(),
web_contents->GetLastCommittedURL(), true, base::DoNothing());
} else if (flash_setting == CONTENT_SETTING_BLOCK) {
auto* settings = content_settings::PageSpecificContentSettings::GetForFrame(
web_contents->GetMainFrame());
if (settings)
settings->FlashDownloadBlocked();
}
// If the content setting has been already changed, do nothing.
}
// static
bool FlashDownloadInterception::ShouldStopFlashDownloadAction(
HostContentSettingsMap* host_content_settings_map,
const GURL& source_url,
const GURL& target_url,
bool has_user_gesture) {
if (!has_user_gesture)
return false;
url::Replacements<char> replacements;
replacements.ClearQuery();
replacements.ClearRef();
replacements.ClearUsername();
replacements.ClearPassword();
// If the navigation source is already the Flash download page, don't
// intercept the download. The user may be trying to download Flash.
std::string source_url_str =
source_url.ReplaceComponents(replacements).GetContent();
std::string target_url_str =
target_url.ReplaceComponents(replacements).GetContent();
// Early optimization since RE2 is expensive. http://crbug.com/809775
if (target_url_str.find("adobe.com") == std::string::npos &&
target_url_str.find("macromedia.com") == std::string::npos)
return false;
if (RE2::PartialMatch(source_url_str, GetFlashURLCanonicalRegex()))
return false;
if (RE2::FullMatch(target_url_str, GetFlashURLCanonicalRegex()) ||
RE2::FullMatch(target_url_str, GetFlashURLSecondaryGoRegex()) ||
(RE2::FullMatch(target_url_str, GetFlashURLSecondaryDownloadRegex()) &&
target_url.query() == kGetFlashURLSecondaryDownloadQuery)) {
ContentSetting flash_setting = PluginUtils::GetFlashPluginContentSetting(
host_content_settings_map, url::Origin::Create(source_url), source_url,
nullptr);
return flash_setting == CONTENT_SETTING_DETECT_IMPORTANT_CONTENT ||
flash_setting == CONTENT_SETTING_BLOCK;
}
return false;
}
// static
std::unique_ptr<NavigationThrottle>
FlashDownloadInterception::MaybeCreateThrottleFor(NavigationHandle* handle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Browser initiated navigations like the Back button or the context menu
// should never be intercepted.
if (!handle->IsRendererInitiated())
return nullptr;
// The source URL may be empty, it's a new tab. Intercepting that navigation
// would lead to a blank new tab, which would be bad.
GURL source_url = handle->GetWebContents()->GetLastCommittedURL();
if (source_url.is_empty())
return nullptr;
// Always treat main-frame navigations as having a user gesture. We have to do
// this because the user gesture system can be foiled by popular JavaScript
// analytics frameworks that capture the click event. crbug.com/678097
bool has_user_gesture = handle->HasUserGesture() || handle->IsInMainFrame();
Profile* profile = Profile::FromBrowserContext(
handle->GetWebContents()->GetBrowserContext());
HostContentSettingsMap* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(profile);
if (!ShouldStopFlashDownloadAction(host_content_settings_map, source_url,
handle->GetURL(), has_user_gesture)) {
return nullptr;
}
return std::make_unique<navigation_interception::InterceptNavigationThrottle>(
handle, base::Bind(&InterceptNavigation, source_url),
navigation_interception::SynchronyMode::kSync);
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PLUGINS_FLASH_DOWNLOAD_INTERCEPTION_H_
#define CHROME_BROWSER_PLUGINS_FLASH_DOWNLOAD_INTERCEPTION_H_
#include <memory>
#include "base/macros.h"
namespace content {
class NavigationHandle;
class NavigationThrottle;
class WebContents;
}
class HostContentSettingsMap;
class GURL;
// This class creates navigation throttles that intercept navigations to Flash's
// download page. The user is queried about activating Flash instead, since
// Chrome already ships with it. Note that this is an UI thread class.
class FlashDownloadInterception {
public:
static void InterceptFlashDownloadNavigation(
content::WebContents* web_contents,
const GURL& source_url);
static bool ShouldStopFlashDownloadAction(
HostContentSettingsMap* host_content_settings_map,
const GURL& source_url,
const GURL& target_url,
bool has_user_gesture);
static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor(
content::NavigationHandle* handle);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(FlashDownloadInterception);
};
#endif // CHROME_BROWSER_PLUGINS_FLASH_DOWNLOAD_INTERCEPTION_H_
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/plugins/flash_download_interception.h"
#include <memory>
#include "base/bind.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_navigation_throttle_inserter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using content::NavigationHandle;
using content::NavigationThrottle;
class FlashDownloadInterceptionTest : public ChromeRenderViewHostTestHarness {
public:
FlashDownloadInterceptionTest() : source_url_("https://source-url.com") {}
HostContentSettingsMap* host_content_settings_map() {
return HostContentSettingsMapFactory::GetForProfile(profile());
}
bool ShouldStopFlashDownloadAction(const std::string& target_url) {
return FlashDownloadInterception::ShouldStopFlashDownloadAction(
host_content_settings_map(), source_url_, GURL(target_url), true);
}
void SetFlashContentSetting(ContentSetting setting) {
host_content_settings_map()->SetContentSettingDefaultScope(
source_url_, source_url_, ContentSettingsType::PLUGINS, std::string(),
setting);
}
private:
const GURL source_url_;
};
TEST_F(FlashDownloadInterceptionTest, DownloadUrlVariations) {
const char* const flash_intercept_urls[] = {
"https://get.adobe.com/flashplayer/",
"http://get2.adobe.com/flashplayer/",
"http://get.adobe.com/flash",
"http://get.adobe.com/fr/flashplayer/",
"http://get.adobe.com/flashplayer",
"http://macromedia.com/go/getflashplayer",
"http://adobe.com/go/getflashplayer",
"http://adobe.com/go/CA-H-GET-FLASH",
"http://adobe.com/go/DE_CH-H-M-A2",
"http://adobe.com/go/gntray_dl_getflashplayer_jp",
("http://www.adobe.com/shockwave/download/download.cgi?"
"P1_Prod_Version=ShockwaveFlash"),
};
for (auto* url : flash_intercept_urls) {
EXPECT_TRUE(ShouldStopFlashDownloadAction(url))
<< "Should have intercepted: " << url;
}
const char* const flash_no_intercept_urls[] = {
"https://www.examplefoo.com",
"http://examplefoo.com/get.adobe.com/flashplayer",
"http://ww.macromedia.com/go/getflashplayer",
"http://wwwxmacromedia.com/go/getflashplayer",
"http://www.adobe.com/software/flash/about/",
"http://www.adobe.com/products/flashplayer.html",
"http://www.adobe.com/products/flashruntimes.html",
"http://www.adobe.com/go/flash",
// Don't intercept URLs containing just "fp" without a matching prefix.
"http://www.adobe.com/go/non-matching-prefix-fp",
// Don't match text within the query or fragment.
"http://www.adobe.com/go/non-matching?foo=flashplayer",
"http://www.adobe.com/go/non-matching#!foo=flashplayer",
("http://www.adobe.com/shockwave/download/download.cgi?"
"P1_Prod_Version=SomethingElse"),
};
for (auto* url : flash_no_intercept_urls) {
EXPECT_FALSE(ShouldStopFlashDownloadAction(url))
<< "Should not have intercepted: " << url;
}
// Don't intercept navigations occurring on the flash download page.
EXPECT_FALSE(FlashDownloadInterception::ShouldStopFlashDownloadAction(
host_content_settings_map(), GURL("https://get.adobe.com/flashplayer/"),
GURL("https://get.adobe.com/flashplayer/"), true));
}
TEST_F(FlashDownloadInterceptionTest, NavigationThrottleCancelsNavigation) {
// Set the source URL to an HTTP source.
NavigateAndCommit(GURL("http://example.com"));
content::TestNavigationThrottleInserter throttle_inserter(
web_contents(),
base::BindRepeating(&FlashDownloadInterception::MaybeCreateThrottleFor));
std::unique_ptr<content::NavigationSimulator> simulator =
content::NavigationSimulator::CreateRendererInitiated(
GURL("https://get.adobe.com/flashplayer"), main_rfh());
simulator->Commit();
EXPECT_EQ(content::NavigationThrottle::CANCEL_AND_IGNORE,
simulator->GetLastThrottleCheckResult());
}
TEST_F(FlashDownloadInterceptionTest, OnlyInterceptOnDetectContentSetting) {
// Default Setting (which is DETECT)
EXPECT_TRUE(
ShouldStopFlashDownloadAction("https://get.adobe.com/flashplayer/"));
// No intercept on ALLOW.
SetFlashContentSetting(CONTENT_SETTING_ALLOW);
EXPECT_FALSE(
ShouldStopFlashDownloadAction("https://get.adobe.com/flashplayer/"));
// Intercept on both explicit DETECT and BLOCK.
SetFlashContentSetting(CONTENT_SETTING_BLOCK);
EXPECT_TRUE(
ShouldStopFlashDownloadAction("https://get.adobe.com/flashplayer/"));
SetFlashContentSetting(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT);
EXPECT_TRUE(
ShouldStopFlashDownloadAction("https://get.adobe.com/flashplayer/"));
}
This diff is collapsed.
......@@ -15,7 +15,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/plugins/flash_download_interception.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/browser/plugins/plugin_infobar_delegates.h"
#include "chrome/browser/plugins/plugin_installer.h"
......@@ -240,8 +239,7 @@ void PluginObserver::RemovePluginPlaceholderHost(
void PluginObserver::ShowFlashPermissionBubble() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
FlashDownloadInterception::InterceptFlashDownloadNavigation(
web_contents(), web_contents()->GetLastCommittedURL());
// TODO(tommycli): This is a no-op now. Delete this method in a followup.
}
void PluginObserver::CouldNotLoadPlugin(const base::FilePath& plugin_path) {
......
......@@ -1178,7 +1178,6 @@ if (!is_android) {
"../browser/permissions/permissions_browsertest.cc",
"../browser/permissions/permissions_browsertest.h",
"../browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc",
"../browser/plugins/flash_permission_browsertest.cc",
"../browser/plugins/plugin_power_saver_browsertest.cc",
"../browser/plugins/plugin_response_interceptor_url_loader_throttle_browsertest.cc",
"../browser/policy/autoplay_policy_browsertest.cc",
......@@ -5615,7 +5614,6 @@ test("unit_tests") {
sources += [
"../browser/metrics/plugin_metrics_provider_unittest.cc",
"../browser/plugins/chrome_plugin_service_filter_unittest.cc",
"../browser/plugins/flash_download_interception_unittest.cc",
"../browser/plugins/flash_temporary_permission_tracker_unittest.cc",
"../browser/plugins/plugin_finder_unittest.cc",
"../browser/plugins/plugin_info_host_impl_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment