diff --git a/browser/renderer_host/BUILD.gn b/browser/renderer_host/BUILD.gn index ec683c63d6d2..03e174f5b2f7 100644 --- a/browser/renderer_host/BUILD.gn +++ b/browser/renderer_host/BUILD.gn @@ -2,6 +2,8 @@ source_set("renderer_host") { sources = [ "brave_navigation_ui_data.cc", "brave_navigation_ui_data.h", + "brave_render_message_filter.cc", + "brave_render_message_filter.h", ] deps = [ diff --git a/browser/renderer_host/brave_render_message_filter.cc b/browser/renderer_host/brave_render_message_filter.cc new file mode 100644 index 000000000000..04f2f59826ba --- /dev/null +++ b/browser/renderer_host/brave_render_message_filter.cc @@ -0,0 +1,77 @@ +/* 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/renderer_host/brave_render_message_filter.h" + +#include "brave/browser/brave_browser_process_impl.h" +#include "brave/components/brave_shields/browser/tracking_protection_service.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/render_messages.h" + +BraveRenderMessageFilter::BraveRenderMessageFilter(int render_process_id, + Profile* profile) + : ChromeRenderMessageFilter(render_process_id, profile), + host_content_settings_map_(HostContentSettingsMapFactory::GetForProfile(profile)) { +} + +BraveRenderMessageFilter::~BraveRenderMessageFilter() {} + +bool BraveRenderMessageFilter::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(BraveRenderMessageFilter, message) + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase); + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage); + IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB); + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return ChromeRenderMessageFilter::OnMessageReceived(message); +} + +void BraveRenderMessageFilter::OnAllowDatabase(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + const base::string16& name, + const base::string16& display_name, + bool* allowed) { + CHECK(g_brave_browser_process->tracking_protection_service()->IsInitialized()); + *allowed = g_brave_browser_process->tracking_protection_service()->ShouldStoreState(host_content_settings_map_, + origin_url, top_origin_url); + + if (*allowed) { + ChromeRenderMessageFilter::OnAllowDatabase(render_frame_id, origin_url, top_origin_url, + name, display_name, allowed); + } +} + +void BraveRenderMessageFilter::OnAllowDOMStorage(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool local, + bool* allowed) { + CHECK(g_brave_browser_process->tracking_protection_service()->IsInitialized()); + *allowed = g_brave_browser_process->tracking_protection_service()->ShouldStoreState(host_content_settings_map_, + origin_url, top_origin_url); + + if (*allowed) { + ChromeRenderMessageFilter::OnAllowDOMStorage(render_frame_id, origin_url, top_origin_url, + local, allowed); + } + +} + +void BraveRenderMessageFilter::OnAllowIndexedDB(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + const base::string16& name, + bool* allowed) { + CHECK(g_brave_browser_process->tracking_protection_service()->IsInitialized()); + *allowed = g_brave_browser_process->tracking_protection_service()->ShouldStoreState(host_content_settings_map_, + origin_url, top_origin_url); + + if (*allowed) { + ChromeRenderMessageFilter::OnAllowIndexedDB(render_frame_id, origin_url, top_origin_url, name, allowed); + } +} \ No newline at end of file diff --git a/browser/renderer_host/brave_render_message_filter.h b/browser/renderer_host/brave_render_message_filter.h new file mode 100644 index 000000000000..f2247202df62 --- /dev/null +++ b/browser/renderer_host/brave_render_message_filter.h @@ -0,0 +1,48 @@ +/* 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/. */ + +#ifndef BRAVE_BROWSER_RENDERER_HOST_BRAVE_RENDER_MESSAGE_FILTER_H_ +#define BRAVE_BROWSER_RENDERER_HOST_BRAVE_RENDER_MESSAGE_FILTER_H_ + +#include "chrome/browser/renderer_host/chrome_render_message_filter.h" +#include "content/public/browser/browser_message_filter.h" + +class HostContentSettingsMap; + +class BraveRenderMessageFilter : public ChromeRenderMessageFilter { + public: + using ChromeRenderMessageFilter::ChromeRenderMessageFilter; + BraveRenderMessageFilter(int render_process_id, Profile* profile); + bool OnMessageReceived(const IPC::Message& message) override; + + private: + friend class base::DeleteHelper; + + ~BraveRenderMessageFilter() override; + + void OnAllowDatabase(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + const base::string16& name, + const base::string16& display_name, + bool* allowed); + + void OnAllowDOMStorage(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + bool local, + bool* allowed); + + void OnAllowIndexedDB(int render_frame_id, + const GURL& origin_url, + const GURL& top_origin_url, + const base::string16& name, + bool* allowed); + + HostContentSettingsMap *host_content_settings_map_; + + DISALLOW_COPY_AND_ASSIGN(BraveRenderMessageFilter); +}; + +#endif // BRAVE_BROWSER_RENDERER_HOST_BRAVE_RENDER_MESSAGE_FILTER_H_ \ No newline at end of file diff --git a/chromium_src/chrome/browser/chrome_content_browser_client.cc b/chromium_src/chrome/browser/chrome_content_browser_client.cc index 5f0806579749..08b34e214c8f 100644 --- a/chromium_src/chrome/browser/chrome_content_browser_client.cc +++ b/chromium_src/chrome/browser/chrome_content_browser_client.cc @@ -4,6 +4,11 @@ #include "build/build_config.h" // For OS_MACOSX +#include "brave/browser/renderer_host/brave_render_message_filter.h" +#include "../../../../chrome/browser/renderer_host/chrome_render_message_filter.h" +#undef ChromeRenderMessageFilter +#define ChromeRenderMessageFilter BraveRenderMessageFilter + #if defined(OS_MACOSX) #include "brave/browser/brave_browser_main_parts_mac.h" #undef ChromeBrowserMainPartsMac diff --git a/components/brave_shields/browser/brave_shields_util.cc b/components/brave_shields/browser/brave_shields_util.cc index 0e0c3cc10792..c7e85b3f635f 100644 --- a/components/brave_shields/browser/brave_shields_util.cc +++ b/components/brave_shields/browser/brave_shields_util.cc @@ -56,9 +56,16 @@ bool IsAllowContentSettingFromIO(net::URLRequest* request, if (!io_data) { return GetDefaultFromResourceIdentifier(resource_identifier); } + return IsAllowContentSetting(io_data->GetHostContentSettingsMap(), primary_url, secondary_url, + setting_type, resource_identifier); +} + +bool IsAllowContentSetting(HostContentSettingsMap* map, + const GURL& primary_url, const GURL& secondary_url, + ContentSettingsType setting_type, + const std::string& resource_identifier) { content_settings::SettingInfo setting_info; - std::unique_ptr value = - io_data->GetHostContentSettingsMap()->GetWebsiteSetting( + std::unique_ptr value = map->GetWebsiteSetting( primary_url, secondary_url, setting_type, resource_identifier, &setting_info); diff --git a/components/brave_shields/browser/brave_shields_util.h b/components/brave_shields/browser/brave_shields_util.h index 6734edd7db5f..bd7ef4ceac2e 100644 --- a/components/brave_shields/browser/brave_shields_util.h +++ b/components/brave_shields/browser/brave_shields_util.h @@ -20,9 +20,15 @@ struct Referrer; } class GURL; +class HostContentSettingsMap; namespace brave_shields { +bool IsAllowContentSetting(HostContentSettingsMap* map, + const GURL& primary_url, const GURL& secondary_url, + ContentSettingsType setting_type, + const std::string& resource_identifier); + bool IsAllowContentSettingFromIO(net::URLRequest* request, const GURL& primary_url, const GURL& secondary_url, ContentSettingsType setting_type, diff --git a/components/brave_shields/browser/tracking_protection_service.cc b/components/brave_shields/browser/tracking_protection_service.cc index eb39de28b151..db3331925964 100644 --- a/components/brave_shields/browser/tracking_protection_service.cc +++ b/components/brave_shields/browser/tracking_protection_service.cc @@ -16,10 +16,14 @@ #include "base/threading/thread_restrictions.h" #include "brave/browser/brave_browser_process_impl.h" #include "brave/components/brave_shields/browser/ad_block_service.h" +#include "brave/components/brave_shields/browser/brave_shields_util.h" #include "brave/components/brave_shields/browser/dat_file_util.h" +#include "brave/components/brave_shields/common/brave_shield_constants.h" #include "brave/vendor/tracking-protection/TPParser.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" -#define DAT_FILE "TrackingProtection.dat" +#define NAVIGATION_TRACKERS_FILE "TrackingProtection.dat" +#define STORAGE_TRACKERS_FILE "StorageTrackingProtection.dat" #define DAT_FILE_VERSION "1" #define THIRD_PARTY_HOSTS_CACHE_SIZE 20 @@ -45,6 +49,7 @@ TrackingProtectionService::TrackingProtectionService() "syndication.twitter.com", "cdn.syndication.twimg.com" }), + first_party_storage_trackers_initailized_(false), weak_factory_(this) { DETACH_FROM_SEQUENCE(sequence_checker_); } @@ -90,6 +95,50 @@ bool TrackingProtectionService::ShouldStartRequest(const GURL& url, return false; } +bool TrackingProtectionService::ShouldStoreState(HostContentSettingsMap* map, const GURL& top_origin_url, + const GURL& origin_url) { + + if (!first_party_storage_trackers_initailized_) { + LOG(INFO) << "First party storage trackers not initialized"; + return true; + } + std::string host = origin_url.host(); + + bool allow_brave_shields = IsAllowContentSetting( + map, top_origin_url, origin_url, CONTENT_SETTINGS_TYPE_PLUGINS, + brave_shields::kBraveShields); + + bool allow_trackers = IsAllowContentSetting( + map, top_origin_url, origin_url, CONTENT_SETTINGS_TYPE_PLUGINS, + brave_shields::kTrackers); + + bool denyStorage = std::find(first_party_storage_trackers_.begin(), first_party_storage_trackers_.end(), host) + != first_party_storage_trackers_.end(); + + return !(allow_brave_shields && !allow_trackers && denyStorage); +} + +void TrackingProtectionService::ParseStorageTrackersData() { + if (storage_trackers_buffer_.empty()) { + LOG(ERROR) << "Could not obtain tracking protection data"; + return; + } + + std::stringstream st(std::string(storage_trackers_buffer_.begin(), storage_trackers_buffer_.end())); + std::string tracker; + + while(std::getline(st, tracker, ',')) { + first_party_storage_trackers_.push_back(tracker); + } + + if(first_party_storage_trackers_.empty()) { + LOG(ERROR) << "No first party trackers found"; + return; + } + + first_party_storage_trackers_initailized_ = true; +} + bool TrackingProtectionService::Init() { Register(kTrackingProtectionComponentName, g_tracking_protection_component_id_, @@ -113,14 +162,23 @@ void TrackingProtectionService::OnComponentReady( const std::string& component_id, const base::FilePath& install_dir, const std::string& manifest) { - base::FilePath dat_file_path = - install_dir.AppendASCII(DAT_FILE_VERSION).AppendASCII(DAT_FILE); - + base::FilePath navigation_tracking_protection_path = + install_dir.AppendASCII(DAT_FILE_VERSION).AppendASCII(NAVIGATION_TRACKERS_FILE); + GetTaskRunner()->PostTaskAndReply( FROM_HERE, - base::Bind(&GetDATFileData, dat_file_path, &buffer_), + base::Bind(&GetDATFileData, navigation_tracking_protection_path, &buffer_), base::Bind(&TrackingProtectionService::OnDATFileDataReady, weak_factory_.GetWeakPtr())); + + base::FilePath storage_tracking_protection_path = + install_dir.AppendASCII(DAT_FILE_VERSION).AppendASCII(STORAGE_TRACKERS_FILE); + + GetTaskRunner()->PostTaskAndReply( + FROM_HERE, + base::Bind(&GetDATFileData, storage_tracking_protection_path, &storage_trackers_buffer_), + base::Bind(&TrackingProtectionService::ParseStorageTrackersData, + weak_factory_.GetWeakPtr())); } // Ported from Android: net/blockers/blockers_worker.cc diff --git a/components/brave_shields/browser/tracking_protection_service.h b/components/brave_shields/browser/tracking_protection_service.h index aa3332f0a3ff..2e1eb80a86d1 100644 --- a/components/brave_shields/browser/tracking_protection_service.h +++ b/components/brave_shields/browser/tracking_protection_service.h @@ -21,6 +21,7 @@ #include "content/public/common/resource_type.h" class CTPParser; +class HostContentSettingsMap; class TrackingProtectionServiceTest; namespace brave_shields { @@ -47,6 +48,8 @@ class TrackingProtectionService : public BaseBraveShieldsService { content::ResourceType resource_type, const std::string& tab_host) override; scoped_refptr GetTaskRunner() override; + bool ShouldStoreState(HostContentSettingsMap* map, + const GURL& top_origin_url, const GURL& origin_url); protected: bool Init() override; @@ -54,6 +57,7 @@ class TrackingProtectionService : public BaseBraveShieldsService { void OnComponentReady(const std::string& component_id, const base::FilePath& install_dir, const std::string& manifest) override; + void ParseStorageTrackersData(); private: friend class ::TrackingProtectionServiceTest; @@ -67,6 +71,7 @@ class TrackingProtectionService : public BaseBraveShieldsService { std::vector GetThirdPartyHosts(const std::string& base_host); brave_shields::DATFileDataBuffer buffer_; + brave_shields::DATFileDataBuffer storage_trackers_buffer_; std::unique_ptr tracking_protection_client_; // TODO: Temporary hack which matches both browser-laptop and Android code @@ -76,6 +81,9 @@ class TrackingProtectionService : public BaseBraveShieldsService { std::mutex third_party_hosts_mutex_; SEQUENCE_CHECKER(sequence_checker_); + std::vector first_party_storage_trackers_; + bool first_party_storage_trackers_initailized_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(TrackingProtectionService); }; diff --git a/patches/chrome-browser-renderer_host-chrome_render_message_filter.h.patch b/patches/chrome-browser-renderer_host-chrome_render_message_filter.h.patch new file mode 100644 index 000000000000..72ce6da2750b --- /dev/null +++ b/patches/chrome-browser-renderer_host-chrome_render_message_filter.h.patch @@ -0,0 +1,20 @@ +diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h +index e1ce2f28510360f9d3e5cefd5c0fdd74e48d61da..5972976ad1fc1b467ba830e7ddf048515a638c0e 100644 +--- a/chrome/browser/renderer_host/chrome_render_message_filter.h ++++ b/chrome/browser/renderer_host/chrome_render_message_filter.h +@@ -18,6 +18,7 @@ + + class GURL; + class Profile; ++class BraveRenderMessageFilter; + + namespace chrome_browser_net { + class Predictor; +@@ -47,6 +48,7 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter { + content::BrowserThread::ID* thread) override; + + private: ++ friend class BraveRenderMessageFilter; + friend class content::BrowserThread; + friend class base::DeleteHelper; +