Implement new WebGL extensions blocking logic
This commit is contained in:
@@ -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 <typename T>
|
||||
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<int64_t> 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<int64_t> 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);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
+36
@@ -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<Vector<String>>
|
||||
WebGLRenderingContextBase::getSupportedExtensions() {
|
||||
base::Optional<Vector<String>> real_extensions =
|
||||
getSupportedExtensions_ChromiumImpl();
|
||||
if (real_extensions == base::nullopt)
|
||||
return real_extensions;
|
||||
if (AllowFingerprintingForHost(Host()))
|
||||
return real_extensions;
|
||||
|
||||
Vector<String> 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
|
||||
|
||||
+22
@@ -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<Vector<String>> 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_
|
||||
+7
-15
@@ -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<Vector<String>>
|
||||
WebGLRenderingContextBase::getSupportedExtensions() {
|
||||
if (isContextLost())
|
||||
return base::nullopt;
|
||||
+ BRAVE_WEBGL_RENDERING_CONTEXT_BASE_NULLOPT
|
||||
|
||||
Vector<String> 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;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WebGL getExtension() test</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="test" width="8" height="8"></canvas>
|
||||
<script>
|
||||
var canvas = document.getElementById("test");
|
||||
var gl = canvas.getContext("webgl");
|
||||
var ext_list = [];
|
||||
for (const [i, name] of Object.entries(gl.getSupportedExtensions())) {
|
||||
ext_list = ext_list.concat(gl.getExtension(name) ? name : null);
|
||||
}
|
||||
document.title = ext_list.join("");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WebGL getSupportedExtensions() test</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="test" width="8" height="8"></canvas>
|
||||
<script>
|
||||
var canvas = document.getElementById("test");
|
||||
var gl = canvas.getContext("webgl");
|
||||
var ext_list = gl.getSupportedExtensions();
|
||||
document.title = ext_list.join(",");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user