Skip to content

Commit

Permalink
implement fingerprinting protection
Browse files Browse the repository at this point in the history
  • Loading branch information
yrliou committed Mar 15, 2018
1 parent ab55e64 commit d23bfc6
Show file tree
Hide file tree
Showing 27 changed files with 849 additions and 0 deletions.
3 changes: 3 additions & 0 deletions common/render_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
// user's content settings.
IPC_MESSAGE_ROUTED1(BraveViewHostMsg_JavaScriptBlocked,
base::string16 /* details on blocked content */)

IPC_MESSAGE_ROUTED1(BraveViewHostMsg_FingerprintingBlocked,
base::string16 /* details on blocked content */)
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ bool BraveShieldsWebContentsObserver::OnMessageReceived(
message, render_frame_host)
IPC_MESSAGE_HANDLER(BraveViewHostMsg_JavaScriptBlocked,
OnJavaScriptBlockedWithDetail)
IPC_MESSAGE_HANDLER(BraveViewHostMsg_FingerprintingBlocked,
OnFingerprintingBlockedWithDetail)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
Expand All @@ -149,6 +151,18 @@ void BraveShieldsWebContentsObserver::OnJavaScriptBlockedWithDetail(
base::UTF16ToUTF8(details), web_contents);
}

void BraveShieldsWebContentsObserver::OnFingerprintingBlockedWithDetail(
RenderFrameHost* render_frame_host,
const base::string16& details) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
if (!web_contents) {
return;
}
DispatchBlockedEventForWebContents(brave_shields::kFingerprinting,
base::UTF16ToUTF8(details), web_contents);
}

// static
void BraveShieldsWebContentsObserver::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterUint64Pref(kAdsBlocked, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class BraveShieldsWebContentsObserver : public content::WebContentsObserver,
void OnJavaScriptBlockedWithDetail(
content::RenderFrameHost* render_frame_host,
const base::string16& details);
void OnFingerprintingBlockedWithDetail(
content::RenderFrameHost* render_frame_host,
const base::string16& details);

DISALLOW_COPY_AND_ASSIGN(BraveShieldsWebContentsObserver);
};
Expand Down
15 changes: 15 additions & 0 deletions patches/chrome-browser-chrome_content_browser_client.cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 8d132058b6ee5ec856a183933ffd389816885619..35ff2e225d6196364ba79d086fef0abe527c259f 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -713,6 +713,10 @@ void GetGuestViewDefaultContentSettingRules(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
content_settings::ContentSettingToValue(CONTENT_SETTING_BLOCK),
std::string(), incognito));
+ rules->fingerprinting_rules.push_back(ContentSettingPatternSource(
+ ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
+ content_settings::ContentSettingToValue(CONTENT_SETTING_ALLOW),
+ std::string(), incognito));
}

AppLoadedInTabSource ClassifyAppLoadedInTabSource(
27 changes: 27 additions & 0 deletions patches/chrome-renderer-content_settings_observer.cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index f3947e48b3a67f534772366ce3ff45bdcc13eb39..c4b62d9087eb65a31085c61306de13eb70ecdce2 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -71,10 +71,12 @@ GURL GetOriginOrURL(const WebFrame* frame) {
return top_origin.GetURL();
}

+} // namespace
+
// Allow passing both WebURL and GURL here, so that we can early return without
// allocating a new backing string if only the default rule matches.
template <typename URL>
-ContentSetting GetContentSettingFromRules(
+ContentSetting ContentSettingsObserver::GetContentSettingFromRules(
const ContentSettingsForOneType& rules,
const WebFrame* frame,
const URL& secondary_url) {
@@ -97,6 +99,8 @@ ContentSetting GetContentSettingFromRules(
return CONTENT_SETTING_DEFAULT;
}

+namespace {
+
bool IsScriptDisabledForPreview(const content::RenderFrame* render_frame) {
return render_frame->GetPreviewsState() & content::NOSCRIPT_ON;
}
25 changes: 25 additions & 0 deletions patches/chrome-renderer-content_settings_observer.h.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
index 8030dcd98b1fc0e227fe07258c4f7f4ecf7fc46f..6532c1de6fc3fbd0f88d6fdcd4ed3bfcd7528b6d 100644
--- a/chrome/renderer/content_settings_observer.h
+++ b/chrome/renderer/content_settings_observer.h
@@ -103,6 +103,7 @@ class ContentSettingsObserver
}

private:
+ friend class BraveContentSettingsObserver;
FRIEND_TEST_ALL_PREFIXES(ContentSettingsObserverTest, WhitelistedSchemes);
FRIEND_TEST_ALL_PREFIXES(ContentSettingsObserverBrowserTest,
ContentSettingsInterstitialPages);
@@ -149,6 +150,12 @@ class ContentSettingsObserver
const blink::WebSecurityOrigin& origin,
const blink::WebURL& document_url);

+ template <typename URL>
+ ContentSetting GetContentSettingFromRules(
+ const ContentSettingsForOneType& rules,
+ const blink::WebFrame* frame,
+ const URL& secondary_url);
+
#if BUILDFLAG(ENABLE_EXTENSIONS)
// Owned by ChromeContentRendererClient and outlive us.
extensions::Dispatcher* const extension_dispatcher_;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc
index 991543e4c6f23831957909b5e60a143c1dd8f091..e40942011faa75a41c8cfaebad2439a172b48a24 100644
--- a/components/content_settings/core/browser/content_settings_utils.cc
+++ b/components/content_settings/core/browser/content_settings_utils.cc
@@ -143,6 +143,10 @@ void GetRendererContentSettingRules(const HostContentSettingsMap* map,
map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_CLIENT_HINTS,
ResourceIdentifier(),
&(rules->client_hints_rules));
+ map->GetSettingsForOneType(
+ CONTENT_SETTINGS_TYPE_PLUGINS,
+ "fingerprinting",
+ &(rules->fingerprinting_rules));
}

bool IsMorePermissive(ContentSetting a, ContentSetting b) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/components/content_settings/core/common/content_settings.h b/components/content_settings/core/common/content_settings.h
index 8fa4e4bef9be06e1cb742a732fb9774f2159c06c..210fad8853b3d17e44270f4151dd62b8cab101bc 100644
--- a/components/content_settings/core/common/content_settings.h
+++ b/components/content_settings/core/common/content_settings.h
@@ -72,6 +72,7 @@ struct RendererContentSettingRules {
ContentSettingsForOneType script_rules;
ContentSettingsForOneType autoplay_rules;
ContentSettingsForOneType client_hints_rules;
+ ContentSettingsForOneType fingerprinting_rules;
};

namespace content_settings {
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
diff --git a/components/content_settings/core/common/content_settings.mojom b/components/content_settings/core/common/content_settings.mojom
index 6766c161ab2345d2cac339d2633ee27ec86d4abe..e2be9fb1bd60a0b2a8633d9220d91b366e94eef0 100644
--- a/components/content_settings/core/common/content_settings.mojom
+++ b/components/content_settings/core/common/content_settings.mojom
@@ -72,4 +72,5 @@ struct RendererContentSettingRules {
array<ContentSettingPatternSource> script_rules;
array<ContentSettingPatternSource> autoplay_rules;
array<ContentSettingPatternSource> client_hints_rules;
+ array<ContentSettingPatternSource> fingerprinting_rules;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/components/content_settings/core/common/content_settings_struct_traits.cc b/components/content_settings/core/common/content_settings_struct_traits.cc
index f3426ddeea0df91b395a039fc87d7db04b51e8ba..5eadd90ee62281032ba0f54be04a67b2a5ff7f9f 100644
--- a/components/content_settings/core/common/content_settings_struct_traits.cc
+++ b/components/content_settings/core/common/content_settings_struct_traits.cc
@@ -100,7 +100,8 @@ bool StructTraits<content_settings::mojom::RendererContentSettingRulesDataView,
return data.ReadImageRules(&out->image_rules) &&
data.ReadScriptRules(&out->script_rules) &&
data.ReadAutoplayRules(&out->autoplay_rules) &&
- data.ReadClientHintsRules(&out->client_hints_rules);
+ data.ReadClientHintsRules(&out->client_hints_rules) &&
+ data.ReadFingerprintingRules(&out->fingerprinting_rules);
}

} // namespace mojo
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/components/content_settings/core/common/content_settings_struct_traits.h b/components/content_settings/core/common/content_settings_struct_traits.h
index f36bdde91be3f6d44f53fd042b707ec2b83b908e..ec7725fcdd2207323d7fc4a8c05b27d3bb961b16 100644
--- a/components/content_settings/core/common/content_settings_struct_traits.h
+++ b/components/content_settings/core/common/content_settings_struct_traits.h
@@ -141,6 +141,11 @@ struct StructTraits<
return r.client_hints_rules;
}

+ static const std::vector<ContentSettingPatternSource>& fingerprinting_rules(
+ const RendererContentSettingRules& r) {
+ return r.fingerprinting_rules;
+ }
+
static bool Read(
content_settings::mojom::RendererContentSettingRulesDataView data,
RendererContentSettingRules* out);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git a/third_party/WebKit/Source/core/frame/ContentSettingsClient.cpp b/third_party/WebKit/Source/core/frame/ContentSettingsClient.cpp
index fde957a1ab1e63c9b5fc66f69015641e42fb10e9..6356ba58c5f77b9c8486023f41c7faf460516bd3 100644
--- a/third_party/WebKit/Source/core/frame/ContentSettingsClient.cpp
+++ b/third_party/WebKit/Source/core/frame/ContentSettingsClient.cpp
@@ -59,6 +59,12 @@ bool ContentSettingsClient::AllowScriptFromSource(bool enabled_per_settings,
return enabled_per_settings;
}

+bool ContentSettingsClient::AllowFingerprinting(bool enabled_per_settings) {
+ if (client_)
+ return client_->AllowFingerprinting(enabled_per_settings);
+ return enabled_per_settings;
+}
+
void ContentSettingsClient::GetAllowedClientHintsFromSource(
const KURL& url,
WebEnabledClientHints* client_hints) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/third_party/WebKit/Source/core/frame/ContentSettingsClient.h b/third_party/WebKit/Source/core/frame/ContentSettingsClient.h
index 54a5a3dd5f92e263b42c265befca66087eaadef7..d78521d2ace8a54b1692dfdfe20df436754f5b10 100644
--- a/third_party/WebKit/Source/core/frame/ContentSettingsClient.h
+++ b/third_party/WebKit/Source/core/frame/ContentSettingsClient.h
@@ -51,6 +51,9 @@ class CORE_EXPORT ContentSettingsClient {
// Controls whether scripts loaded from the given URL are allowed to execute.
bool AllowScriptFromSource(bool enabled_per_settings, const KURL&);

+ // Controls whether fingerprinting is allowed for this frame.
+ bool AllowFingerprinting(bool enabled_per_settings);
+
// Retrieves the client hints that should be attached to the request for the
// given URL.
void GetAllowedClientHintsFromSource(const KURL&, WebEnabledClientHints*);
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git a/third_party/WebKit/Source/core/html/canvas/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/canvas/HTMLCanvasElement.cpp
index 8f5c621ca932513988e143ad5b0863f5b2af381f..24449d804c4da8e8a7a0e0a90a4f3c05935a6256 100644
--- a/third_party/WebKit/Source/core/html/canvas/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/HTMLCanvasElement.cpp
@@ -35,6 +35,7 @@
#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ScriptController.h"
+#include "brave/renderer/brave_content_settings_observer_helper.h"
#include "build/build_config.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/StyleEngine.h"
@@ -820,6 +821,9 @@ String HTMLCanvasElement::ToDataURLInternal(
String HTMLCanvasElement::toDataURL(const String& mime_type,
const ScriptValue& quality_argument,
ExceptionState& exception_state) const {
+ if (!AllowFingerprinting(GetDocument().GetFrame()))
+ return String();
+
if (!OriginClean()) {
exception_state.ThrowSecurityError("Tainted canvases may not be exported.");
return String();
@@ -839,6 +843,9 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback,
const String& mime_type,
const ScriptValue& quality_argument,
ExceptionState& exception_state) {
+ if (!AllowFingerprinting(GetDocument().GetFrame()))
+ return;
+
if (!OriginClean()) {
exception_state.ThrowSecurityError("Tainted canvases may not be exported.");
return;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diff --git a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
index 0cd5644ddaf02669ed5bb452ee89d558ea6a6399..c0b86e4cbf9a7283ef3ff0b87ab9bd438f23dbc3 100644
--- a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
@@ -20,6 +20,7 @@

#include "core/svg/SVGPathElement.h"

+#include "brave/renderer/brave_content_settings_observer_helper.h"
#include "core/css/StyleChangeReason.h"
#include "core/layout/svg/LayoutSVGPath.h"
#include "core/svg/SVGMPathElement.h"
@@ -65,6 +66,9 @@ Path SVGPathElement::AsPath() const {
}

float SVGPathElement::getTotalLength() {
+ if (!AllowFingerprinting(GetDocument().GetFrame())) {
+ return 0.0f;
+ }
GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
return SVGPathQuery(PathByteStream()).GetTotalLength();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diff --git a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
index d8b1e5b163a7d1663ef692a2e5a3393711784b0d..d5762fb3b08e8acb51196bcae94849ec3d73874d 100644
--- a/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
@@ -22,6 +22,7 @@

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
+#include "brave/renderer/brave_content_settings_observer_helper.h"
#include "core/CSSPropertyNames.h"
#include "core/CSSValueKeywords.h"
#include "core/editing/FrameSelection.h"
@@ -103,6 +104,9 @@ unsigned SVGTextContentElement::getNumberOfChars() {
}

float SVGTextContentElement::getComputedTextLength() {
+ if (!AllowFingerprinting(GetDocument().GetFrame())) {
+ return 0.0f;
+ }
GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
return SVGTextQuery(GetLayoutObject()).TextLength();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
index 94de909f954d2f4638a89aa37575e39626989ae8..76a8211b23d69ef4efe070baa2d7153af82bc355 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.cpp
@@ -36,6 +36,7 @@
#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/modules/v8/rendering_context.h"
+#include "brave/renderer/brave_content_settings_observer_helper.h"
#include "core/CSSPropertyNames.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSPropertyValueSet.h"
@@ -763,6 +764,9 @@ TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
if (!canvas()->GetDocument().GetFrame())
return TextMetrics::Create();

+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame()))
+ return TextMetrics::Create();
+
canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas());

const Font& font = AccessFont();
@@ -778,6 +782,52 @@ TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
GetState().GetTextAlign(), text);
}

+bool CanvasRenderingContext2D::isPointInPath(const double x,
+ const double y,
+ const String& winding_rule_string) {
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) return false;
+ return BaseRenderingContext2D::isPointInPath(x, y, winding_rule_string);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(Path2D* dom_path,
+ const double x,
+ const double y,
+ const String& winding_rule_string) {
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) return false;
+ return BaseRenderingContext2D::isPointInPath(dom_path, x, y,
+ winding_rule_string);
+}
+
+bool CanvasRenderingContext2D::isPointInStroke(const double x, const double y) {
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) return false;
+ return BaseRenderingContext2D::isPointInStroke(x, y);
+}
+
+bool CanvasRenderingContext2D::isPointInStroke(Path2D* dom_path,
+ const double x,
+ const double y) {
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) return false;
+ return BaseRenderingContext2D::isPointInStroke(dom_path, x, y);
+}
+
+ImageData* CanvasRenderingContext2D::getImageData(
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ ExceptionState& exception_state) {
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) return nullptr;
+ return BaseRenderingContext2D::getImageData(sx, sy, sw, sh, exception_state);
+}
+
+const Vector<double>& CanvasRenderingContext2D::getLineDash() const {
+ static const Vector<double> emptyVector;
+ if (!AllowFingerprinting(canvas()->GetDocument().GetFrame())) {
+ return emptyVector;
+ }
+ return BaseRenderingContext2D::getLineDash();
+}
+
void CanvasRenderingContext2D::DrawTextInternal(
const String& text,
double x,
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
diff --git a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
index 1fface0bbb6ee9bd97ab49a0e0577a84a5228b5d..04e72634a50f13d97bc89319e7b319fb612e8da2 100644
--- a/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
+++ b/third_party/WebKit/Source/modules/canvas/canvas2d/CanvasRenderingContext2D.h
@@ -124,6 +124,19 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void strokeText(const String& text, double x, double y, double max_width);
TextMetrics* measureText(const String& text);

+ bool isPointInPath(const double x,
+ const double y,
+ const String& winding = "nonzero");
+ bool isPointInPath(Path2D*,
+ const double x,
+ const double y,
+ const String& winding = "nonzero");
+ bool isPointInStroke(const double x, const double y);
+ bool isPointInStroke(Path2D*, const double x, const double y);
+ ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&);
+ const Vector<double>& getLineDash() const;
+
+
void getContextAttributes(CanvasRenderingContext2DSettings&) const;

void drawFocusIfNeeded(Element*);
Loading

0 comments on commit d23bfc6

Please sign in to comment.