diff --git a/browser/farbling/brave_webgl_farbling_browsertest.cc b/browser/farbling/brave_webgl_farbling_browsertest.cc index af32dc2de48..b6a8c861110 100644 --- a/browser/farbling/brave_webgl_farbling_browsertest.cc +++ b/browser/farbling/brave_webgl_farbling_browsertest.cc @@ -29,7 +29,7 @@ using brave_shields::ControlType; const char kEmbeddedTestServerDirectory[] = "webgl"; -const char kTitleScript[] = "domAutomationController.send(document.title);"; +const char kTitleScript[] = "document.title"; class BraveWebGLFarblingBrowserTest : public InProcessBrowserTest { public: @@ -80,13 +80,6 @@ class BraveWebGLFarblingBrowserTest : public InProcessBrowserTest { embedded_test_server()->GetURL(domain, "/")); } - template - std::string ExecScriptGetStr(const std::string& script, T* frame) { - std::string value; - EXPECT_TRUE(ExecuteScriptAndExtractString(frame, script, &value)); - return value; - } - content::WebContents* contents() { return browser()->tab_strip_model()->GetActiveWebContents(); } @@ -131,19 +124,20 @@ IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, FarbleGetParameterWebGL) { // relation to original data BlockFingerprinting(domain); NavigateToURLUntilLoadStop(url); - EXPECT_EQ(ExecScriptGetStr(kTitleScript, contents()), kExpectedRandomString); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), + kExpectedRandomString); // second time, same as the first (tests that results are consistent for the // lifetime of a session, and that the PRNG properly resets itself at the // beginning of each calculation) NavigateToURLUntilLoadStop(url); - EXPECT_EQ(ExecScriptGetStr(kTitleScript, contents()), kExpectedRandomString); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), + kExpectedRandomString); - std::string actual; // Farbling level: balanced (default) // WebGL getParameter of restricted values: original data SetFingerprintingDefault(domain); NavigateToURLUntilLoadStop(url); - actual = ExecScriptGetStr(kTitleScript, contents()); + std::string actual = EvalJs(contents(), kTitleScript).ExtractString(); // Farbling level: off // WebGL getParameter of restricted values: original data @@ -152,8 +146,8 @@ IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, FarbleGetParameterWebGL) { // Since this value depends on the underlying hardware, we just test that the // results for "off" are the same as the results for "balanced", and that // they're different than the results for "maximum". - EXPECT_EQ(ExecScriptGetStr(kTitleScript, contents()), actual); - EXPECT_NE(kExpectedRandomString, actual); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), actual); + EXPECT_NE(actual, kExpectedRandomString); } IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, @@ -172,7 +166,7 @@ IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, AllowFingerprinting(domain); NavigateToURLUntilLoadStop(url); std::vector real_values = - SplitStringAsInts(ExecScriptGetStr(kTitleScript, contents())); + SplitStringAsInts(EvalJs(contents(), kTitleScript).ExtractString()); ASSERT_EQ(real_values.size(), 12UL); // Farbling level: default @@ -181,8 +175,59 @@ IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, SetFingerprintingDefault(domain); NavigateToURLUntilLoadStop(url); std::vector farbled_values = - SplitStringAsInts(ExecScriptGetStr(kTitleScript, contents())); + SplitStringAsInts(EvalJs(contents(), kTitleScript).ExtractString()); ASSERT_EQ(farbled_values.size(), 12UL); ASSERT_EQ(DiffsAsString(real_values, farbled_values), expected_diff); } } + +IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, GetSupportedExtensions) { + std::string domain = "a.com"; + GURL url = + embedded_test_server()->GetURL(domain, "/getSupportedExtensions.html"); + const std::string kSupportedExtensionsMax = "WEBGL_debug_renderer_info"; + // Farbling level: maximum + // WebGL getSupportedExtensions returns abbreviated list + BlockFingerprinting(domain); + NavigateToURLUntilLoadStop(url); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), + kSupportedExtensionsMax); + + // Farbling level: off + // WebGL getSupportedExtensions is real + AllowFingerprinting(domain); + NavigateToURLUntilLoadStop(url); + std::string actual = EvalJs(contents(), kTitleScript).ExtractString(); + EXPECT_NE(actual, kSupportedExtensionsMax); + + // Farbling level: balanced (default) + // WebGL getSupportedExtensions is real + SetFingerprintingDefault(domain); + NavigateToURLUntilLoadStop(url); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), actual); +} + +IN_PROC_BROWSER_TEST_F(BraveWebGLFarblingBrowserTest, GetExtension) { + std::string domain = "a.com"; + GURL url = embedded_test_server()->GetURL(domain, "/getExtension.html"); + const std::string kExpectedExtensionListMax = "WEBGL_debug_renderer_info"; + // Farbling level: maximum + // WebGL getExtension returns null for most names + BlockFingerprinting(domain); + NavigateToURLUntilLoadStop(url); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), + kExpectedExtensionListMax); + + // Farbling level: off + // WebGL getExtension returns real objects + AllowFingerprinting(domain); + NavigateToURLUntilLoadStop(url); + std::string actual = EvalJs(contents(), kTitleScript).ExtractString(); + EXPECT_NE(actual, kExpectedExtensionListMax); + + // Farbling level: balanced (default) + // WebGL getExtension returns real objects + SetFingerprintingDefault(domain); + NavigateToURLUntilLoadStop(url); + EXPECT_EQ(EvalJs(contents(), kTitleScript).ExtractString(), actual); +} diff --git a/chromium_src/third_party/blink/renderer/DEPS b/chromium_src/third_party/blink/renderer/DEPS index 418f02eb16d..dfc61c3e4d2 100644 --- a/chromium_src/third_party/blink/renderer/DEPS +++ b/chromium_src/third_party/blink/renderer/DEPS @@ -13,6 +13,7 @@ include_rules = [ "+../../../../../../../third_party/blink/renderer/modules/mediastream", "+../../../../../../../third_party/blink/renderer/modules/quota", "+../../../../../../../third_party/blink/renderer/modules/storage", + "+../../../../../../third_party/blink/renderer/modules/webgl", "+../../../../../../../third_party/blink/renderer/modules/webaudio", "+../../../../../../../../third_party/blink/renderer/modules/canvas/canvas2d", "+../../../../../../../third_party/blink/renderer/platform/graphics", diff --git a/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 752b7c5c4f5..55c32732698 100644 --- a/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc @@ -3,6 +3,7 @@ * 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 "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -77,7 +78,42 @@ bool AllowFingerprintingForHost(blink::CanvasRenderingContextHost* host) { *(Host()->GetTopExecutionContext())) \ .GenerateRandomString("UNMASKED_VENDOR_WEBGL", 8))); +#define getExtension getExtension_ChromiumImpl +#define getSupportedExtensions getSupportedExtensions_ChromiumImpl #include "../../../../../../../third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc" +#undef getSupportedExtensions +#undef getExtension + +namespace blink { + +// If fingerprinting is disallowed, claim that the only supported extension is +// WebGLDebugRendererInfo. +base::Optional> +WebGLRenderingContextBase::getSupportedExtensions() { + base::Optional> real_extensions = + getSupportedExtensions_ChromiumImpl(); + if (real_extensions == base::nullopt) + return real_extensions; + if (AllowFingerprintingForHost(Host())) + return real_extensions; + + Vector fake_extensions; + fake_extensions.push_back(WebGLDebugRendererInfo::ExtensionName()); + return fake_extensions; +} + +// If fingerprinting is disallowed and they're asking for information about any +// extension other than WebGLDebugRendererInfo, don't give it to them. +ScriptValue WebGLRenderingContextBase::getExtension(ScriptState* script_state, + const String& name) { + if (!AllowFingerprintingForHost(Host())) + if (name != WebGLDebugRendererInfo::ExtensionName()) + return ScriptValue::CreateNull(script_state->GetIsolate()); + return getExtension_ChromiumImpl(script_state, name); +} + +} // namespace blink + #undef BRAVE_WEBGL_GET_PARAMETER_UNMASKED_RENDERER #undef BRAVE_WEBGL_GET_PARAMETER_UNMASKED_VENDOR #undef BRAVE_WEBGL_RENDERING_CONTEXT_BASE_STRING diff --git a/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h new file mode 100644 index 00000000000..aaf4bcf6931 --- /dev/null +++ b/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2021 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 https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_ +#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_ + +#define getExtension \ + getExtension_ChromiumImpl(ScriptState*, const String& name); \ + ScriptValue getExtension + +#define getSupportedExtensions \ + getSupportedExtensions_ChromiumImpl(); \ + base::Optional> getSupportedExtensions + +#include "../../../../../../third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h" + +#undef getSupportedExtensions +#undef getExtension + +#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_RENDERING_CONTEXT_BASE_H_ diff --git a/patches/third_party-blink-renderer-modules-webgl-webgl_rendering_context_base.cc.patch b/patches/third_party-blink-renderer-modules-webgl-webgl_rendering_context_base.cc.patch index b9fe0fd7f27..746fca43ace 100644 --- a/patches/third_party-blink-renderer-modules-webgl-webgl_rendering_context_base.cc.patch +++ b/patches/third_party-blink-renderer-modules-webgl-webgl_rendering_context_base.cc.patch @@ -1,5 +1,5 @@ diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc -index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9bf57a51d 100644 +index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..70adc89b0c804f28d8c94e6217d9dd650f97a5ac 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc @@ -2920,6 +2920,7 @@ WebGLActiveInfo* WebGLRenderingContextBase::getActiveAttrib( @@ -122,15 +122,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 return EnsureNotNull(shader->Source()); } -@@ -3868,6 +3883,7 @@ base::Optional> - WebGLRenderingContextBase::getSupportedExtensions() { - if (isContextLost()) - return base::nullopt; -+ BRAVE_WEBGL_RENDERING_CONTEXT_BASE_NULLOPT - - Vector result; - -@@ -3890,6 +3906,7 @@ ScriptValue WebGLRenderingContextBase::getTexParameter( +@@ -3890,6 +3905,7 @@ ScriptValue WebGLRenderingContextBase::getTexParameter( GLenum pname) { if (isContextLost()) return ScriptValue::CreateNull(script_state->GetIsolate()); @@ -138,7 +130,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 if (!ValidateTextureBinding("getTexParameter", target)) return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { -@@ -3924,6 +3941,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( +@@ -3924,6 +3940,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( const WebGLUniformLocation* uniform_location) { if (!ValidateWebGLProgramOrShader("getUniform", program)) return ScriptValue::CreateNull(script_state->GetIsolate()); @@ -146,7 +138,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 DCHECK(uniform_location); if (uniform_location->Program() != program) { SynthesizeGLError(GL_INVALID_OPERATION, "getUniform", -@@ -4183,6 +4201,7 @@ WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( +@@ -4183,6 +4200,7 @@ WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( const String& name) { if (!ValidateWebGLProgramOrShader("getUniformLocation", program)) return nullptr; @@ -154,7 +146,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 if (!ValidateLocationLength("getUniformLocation", name)) return nullptr; if (!ValidateString("getUniformLocation", name)) -@@ -4207,6 +4226,7 @@ ScriptValue WebGLRenderingContextBase::getVertexAttrib( +@@ -4207,6 +4225,7 @@ ScriptValue WebGLRenderingContextBase::getVertexAttrib( GLenum pname) { if (isContextLost()) return ScriptValue::CreateNull(script_state->GetIsolate()); @@ -162,7 +154,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 if (index >= max_vertex_attribs_) { SynthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range"); -@@ -4284,6 +4304,7 @@ int64_t WebGLRenderingContextBase::getVertexAttribOffset(GLuint index, +@@ -4284,6 +4303,7 @@ int64_t WebGLRenderingContextBase::getVertexAttribOffset(GLuint index, GLenum pname) { if (isContextLost()) return 0; @@ -170,7 +162,7 @@ index 31a22fa48c001a07d1b848c107d22c7d1342c2a6..598a94a2cb71897c4ace95dbecfb8cd9 GLvoid* result = nullptr; // NOTE: If pname is ever a value that returns more than 1 element // this will corrupt memory. -@@ -4631,6 +4652,7 @@ void WebGLRenderingContextBase::ReadPixelsHelper(GLint x, +@@ -4631,6 +4651,7 @@ void WebGLRenderingContextBase::ReadPixelsHelper(GLint x, int64_t offset) { if (isContextLost()) return; diff --git a/test/data/webgl/getExtension.html b/test/data/webgl/getExtension.html new file mode 100644 index 00000000000..67bb76b9740 --- /dev/null +++ b/test/data/webgl/getExtension.html @@ -0,0 +1,21 @@ + + + + WebGL getExtension() test + + + + + + + + + } diff --git a/test/data/webgl/getSupportedExtensions.html b/test/data/webgl/getSupportedExtensions.html new file mode 100644 index 00000000000..14cd0cfc563 --- /dev/null +++ b/test/data/webgl/getSupportedExtensions.html @@ -0,0 +1,16 @@ + + + + WebGL getSupportedExtensions() test + + + + + + +