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

Implement canvas blocking v2 #5541

Merged
merged 1 commit into from
May 29, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,66 @@
* 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/renderer/brave_content_settings_agent_impl_helper.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"

#define BRAVE_GET_IMAGE_DATA \
LocalDOMWindow* window = LocalDOMWindow::From(script_state); \
if (window) { \
snapshot = brave::BraveSessionCache::From(*(window->document())) \
.PerturbPixels(window->document()->GetFrame(), snapshot); \
#define BRAVE_GET_IMAGE_DATA \
LocalDOMWindow* window = LocalDOMWindow::From(script_state); \
if (window) { \
snapshot = brave::BraveSessionCache::From(*(window->document())) \
.PerturbPixels(window->document()->GetFrame(), snapshot); \
}

#include "../../../../../../../third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc"

namespace {

bool AllowFingerprintingFromScriptState(blink::ScriptState* script_state) {
blink::LocalDOMWindow* window = blink::LocalDOMWindow::From(script_state);
return !window || AllowFingerprinting(window->GetFrame());
}

} // namespace

namespace blink {

bool BaseRenderingContext2D::isPointInPath(ScriptState* script_state,
const double x,
const double y,
const String& winding_rule_string) {
if (!AllowFingerprintingFromScriptState(script_state))
return false;
return isPointInPath(x, y, winding_rule_string);
}

bool BaseRenderingContext2D::isPointInPath(ScriptState* script_state,
Path2D* dom_path,
const double x,
const double y,
const String& winding_rule_string) {
if (!AllowFingerprintingFromScriptState(script_state))
return false;
return isPointInPath(dom_path, x, y, winding_rule_string);
}

bool BaseRenderingContext2D::isPointInStroke(ScriptState* script_state,
const double x,
const double y) {
if (!AllowFingerprintingFromScriptState(script_state))
return false;
return isPointInStroke(x, y);
}

bool BaseRenderingContext2D::isPointInStroke(ScriptState* script_state,
Path2D* dom_path,
const double x,
const double y) {
if (!AllowFingerprintingFromScriptState(script_state))
return false;
return isPointInStroke(dom_path, x, y);
}

} // namespace blink

#undef BRAVE_GET_IMAGE_DATA
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
* 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_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BASE_RENDERING_CONTEXT_2D_H_
#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BASE_RENDERING_CONTEXT_2D_H_

#define BRAVE_BASE_RENDERING_CONTEXT_2D_H \
bool isPointInPath(ScriptState*, const double x, const double y, \
const String& winding = "nonzero"); \
bool isPointInPath(ScriptState*, Path2D*, const double x, const double y, \
const String& winding = "nonzero"); \
bool isPointInStroke(ScriptState*, const double x, const double y); \
bool isPointInStroke(ScriptState*, Path2D*, const double x, const double y);

#include "../../../../../../../third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"

#undef BRAVE_BASE_RENDERING_CONTEXT_2D_H

#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BASE_RENDERING_CONTEXT_2D_H_
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 9fd5cb6cb4835b4f42ca1d8c3c90fd4a34623ac7..939dbd47fea6ebc23ac3b438aa0ad8d0c5014a91 100644
index 9fd5cb6cb4835b4f42ca1d8c3c90fd4a34623ac7..eab244c20bdcfabb827652bbe0c4c904b379079e 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -195,7 +195,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
Expand All @@ -11,3 +11,11 @@ index 9fd5cb6cb4835b4f42ca1d8c3c90fd4a34623ac7..939dbd47fea6ebc23ac3b438aa0ad8d0
void putImageData(ImageData*, int dx, int dy, ExceptionState&);
void putImageData(ImageData*,
int dx,
@@ -314,6 +314,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,

const UsageCounters& GetUsage();

+ BRAVE_BASE_RENDERING_CONTEXT_2D_H
protected:
BaseRenderingContext2D();

Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
index b4b6ae1e108614dfb2e20eb51922cd98efdd6ae5..321bdc99bf9eb74e9fdc64634ff17f5e9d0ea459 100644
index b4b6ae1e108614dfb2e20eb51922cd98efdd6ae5..bc25aef7b3aa38b39a0a264978073bb04258cf28 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
@@ -126,7 +126,7 @@ interface CanvasRenderingContext2D {
@@ -103,9 +103,13 @@ interface CanvasRenderingContext2D {
[RuntimeEnabled=Canvas2dScrollPathIntoView] void scrollPathIntoView(optional Path2D path);
void clip(optional CanvasFillRule winding);
void clip(Path2D path, optional CanvasFillRule winding);
+ [CallWith=ScriptState]
boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState]
boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState]
boolean isPointInStroke(unrestricted double x, unrestricted double y);
+ [CallWith=ScriptState]
boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);

// text (see also the CanvasDrawingStyles interface)
@@ -126,7 +130,7 @@ interface CanvasRenderingContext2D {
// pixel manipulation
[RaisesException] ImageData createImageData(ImageData imagedata);
[RaisesException] ImageData createImageData([EnforceRange] long sw, [EnforceRange] long sh);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
index 4371777bcd68c6e334d12a0ba5fd38874cdbdd49..657e9eee13c50f92b11cf5c77aee825c3a561bac 100644
index 4371777bcd68c6e334d12a0ba5fd38874cdbdd49..c6cb08969bd211ef1eed06f1fc9d5d74a210f1a4 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -62,10 +62,10 @@
void stroke(Path2D path);
void clip(optional CanvasFillRule winding);
void clip(Path2D path, optional CanvasFillRule winding);
- [HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
- [HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
- [HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(unrestricted double x, unrestricted double y);
- [HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);
+ [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasIsPointInPath] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(unrestricted double x, unrestricted double y);
+ [CallWith=ScriptState, HighEntropy, MeasureAs=OffscreenCanvasIsPointInStroke] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);

// text (see also the CanvasDrawingStyles interface)
void fillText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
@@ -80,7 +80,7 @@
// pixel manipulation
[RaisesException] ImageData createImageData(ImageData imagedata);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
index 94d6d46580570a81e0baf12dc042262ccc84899a..b23ce72df411e63a17a2d2508a735ec127a4bd04 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
+++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
@@ -58,10 +58,10 @@

void clip(optional CanvasFillRule winding);
void clip(Path2D path, optional CanvasFillRule winding);
- [HighEntropy, Measure] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
- [HighEntropy, Measure] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
- [HighEntropy, Measure] boolean isPointInStroke(unrestricted double x, unrestricted double y);
- [HighEntropy, Measure] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);
+ [CallWith=ScriptState, HighEntropy, Measure] boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState, HighEntropy, Measure] boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule winding);
+ [CallWith=ScriptState, HighEntropy, Measure] boolean isPointInStroke(unrestricted double x, unrestricted double y);
+ [CallWith=ScriptState, HighEntropy, Measure] boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y);

// drawing images
[CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double x, unrestricted double y);
10 changes: 5 additions & 5 deletions renderer/brave_content_settings_agent_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ bool IsBraveShieldsDown(const blink::WebFrame* frame,
return setting == CONTENT_SETTING_BLOCK;
}

// This method can only be used for brave plugin content settings because
// they are implemented incorrectly and swap primary/secondary url
template <typename URL>
ContentSetting GetBraveContentSettingFromRules(
const ContentSettingsForOneType& shield_rules,
Expand All @@ -79,9 +77,8 @@ ContentSetting GetBraveContentSettingFromRules(
const GURL& primary_url = GetOriginOrURL(frame);
const GURL& secondary_gurl = secondary_url;
for (const auto& rule : rules) {
// this swap is intentional - see comment at the beginning of the method
if (rule.primary_pattern.Matches(secondary_gurl) &&
rule.secondary_pattern.Matches(primary_url)) {
if (rule.primary_pattern.Matches(primary_url) &&
rule.secondary_pattern.Matches(secondary_gurl)) {
return rule.GetContentSetting();
}
}
Expand Down Expand Up @@ -295,10 +292,13 @@ BraveFarblingLevel BraveContentSettingsAgentImpl::GetBraveFarblingLevel() {
if (base::FeatureList::IsEnabled(
brave_shields::features::kFingerprintingProtectionV2)) {
if (setting == CONTENT_SETTING_BLOCK) {
VLOG(1) << "farbling level MAXIMUM";
return BraveFarblingLevel::MAXIMUM;
} else if (setting == CONTENT_SETTING_ALLOW) {
VLOG(1) << "farbling level OFF";
return BraveFarblingLevel::OFF;
} else {
VLOG(1) << "farbling level BALANCED";
return BraveFarblingLevel::BALANCED;
}
} else {
Expand Down
65 changes: 63 additions & 2 deletions renderer/brave_content_settings_agent_impl_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ namespace {

const char kIframeID[] = "test";

const char kPointInPathScript[] =
"var canvas = document.createElement('canvas');"
"var ctx = canvas.getContext('2d');"
"ctx.rect(10, 10, 100, 100);"
"ctx.stroke();"
"domAutomationController.send(ctx.isPointInPath(10, 10));";

const char kGetImageDataScript[] =
"var adder = (a, x) => a + x;"
"var canvas = document.createElement('canvas');"
Expand Down Expand Up @@ -59,8 +66,7 @@ const char kCookieScript[] =
const char kReferrerScript[] =
"domAutomationController.send(document.referrer);";

const char kTitleScript[] =
"domAutomationController.send(document.title);";
const char kTitleScript[] = "domAutomationController.send(document.title);";

} // namespace

Expand Down Expand Up @@ -487,6 +493,61 @@ IN_PROC_BROWSER_TEST_F(BraveContentSettingsAgentImplV2BrowserTest,
EXPECT_EQ(kExpectedImageDataHashFarblingOff, hash);
}

IN_PROC_BROWSER_TEST_F(BraveContentSettingsAgentImplV2BrowserTest,
CanvasIsPointInPath) {
bool isPointInPath;

// Farbling level: maximum
// Canvas isPointInPath(): blocked
BlockFingerprinting();
NavigateToPageWithIframe();
EXPECT_TRUE(ExecuteScriptAndExtractBool(contents(), kPointInPathScript,
&isPointInPath));
EXPECT_FALSE(isPointInPath);
NavigateIframe(cross_site_url());
EXPECT_TRUE(ExecuteScriptAndExtractBool(child_frame(), kPointInPathScript,
&isPointInPath));
EXPECT_FALSE(isPointInPath);

// Farbling level: balanced (default)
// Canvas isPointInPath(): allowed
SetFingerprintingDefault();
NavigateToPageWithIframe();
EXPECT_TRUE(ExecuteScriptAndExtractBool(contents(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);
NavigateIframe(cross_site_url());
EXPECT_TRUE(ExecuteScriptAndExtractBool(child_frame(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);

// Farbling level: off
// Canvas isPointInPath(): allowed
AllowFingerprinting();
NavigateToPageWithIframe();
EXPECT_TRUE(ExecuteScriptAndExtractBool(contents(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);
NavigateIframe(cross_site_url());
EXPECT_TRUE(ExecuteScriptAndExtractBool(child_frame(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);

// Shields: down
// Canvas isPointInPath(): allowed
BlockFingerprinting();
ShieldsDown();
AllowFingerprinting();
NavigateToPageWithIframe();
EXPECT_TRUE(ExecuteScriptAndExtractBool(contents(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);
NavigateIframe(cross_site_url());
EXPECT_TRUE(ExecuteScriptAndExtractBool(child_frame(), kPointInPathScript,
&isPointInPath));
EXPECT_TRUE(isPointInPath);
}

IN_PROC_BROWSER_TEST_F(BraveContentSettingsAgentImplBrowserTest,
BlockReferrerByDefault) {
ContentSettingsForOneType settings;
Expand Down