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 navigator.hardwareConcurrency farbling #6156

Merged
merged 1 commit into from
Aug 13, 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
@@ -0,0 +1,145 @@
/* 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/. */

#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/test/thread_test_helper.h"
#include "brave/browser/brave_browser_process_impl.h"
#include "brave/browser/brave_content_browser_client.h"
#include "brave/browser/extensions/brave_base_local_data_files_browsertest.h"
#include "brave/common/brave_paths.h"
#include "brave/common/pref_names.h"
#include "brave/components/brave_component_updater/browser/local_data_files_service.h"
#include "brave/components/brave_shields/browser/brave_shields_util.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/permissions/permission_request.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"

using brave_shields::ControlType;

const char kHardwareConcurrencyScript[] =
"domAutomationController.send(navigator.hardwareConcurrency);";

class BraveNavigatorHardwareConcurrencyFarblingBrowserTest
: public InProcessBrowserTest {
public:
void SetUpOnMainThread() override {
InProcessBrowserTest::SetUpOnMainThread();

content_client_.reset(new ChromeContentClient);
content::SetContentClient(content_client_.get());
browser_content_client_.reset(new BraveContentBrowserClient());
content::SetBrowserClientForTesting(browser_content_client_.get());

host_resolver()->AddRule("*", "127.0.0.1");
content::SetupCrossSiteRedirector(embedded_test_server());

brave::RegisterPathProvider();
base::FilePath test_data_dir;
base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);

ASSERT_TRUE(embedded_test_server()->Start());

top_level_page_url_ = embedded_test_server()->GetURL("a.com", "/");
farbling_url_ = embedded_test_server()->GetURL("a.com", "/simple.html");
}

void TearDown() override {
browser_content_client_.reset();
content_client_.reset();
}

const GURL& farbling_url() { return farbling_url_; }

HostContentSettingsMap* content_settings() {
return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
}

void AllowFingerprinting() {
brave_shields::SetFingerprintingControlType(
content_settings(), ControlType::ALLOW, top_level_page_url_);
}

void BlockFingerprinting() {
brave_shields::SetFingerprintingControlType(
content_settings(), ControlType::BLOCK, top_level_page_url_);
}

void SetFingerprintingDefault() {
brave_shields::SetFingerprintingControlType(
content_settings(), ControlType::DEFAULT, top_level_page_url_);
}

template <typename T>
int ExecScriptGetInt(const std::string& script, T* frame) {
int value;
EXPECT_TRUE(ExecuteScriptAndExtractInt(frame, script, &value));
return value;
}

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();
}

bool NavigateToURLUntilLoadStop(const GURL& url) {
ui_test_utils::NavigateToURL(browser(), url);
return WaitForLoadStop(contents());
}

private:
GURL top_level_page_url_;
GURL farbling_url_;
std::unique_ptr<ChromeContentClient> content_client_;
std::unique_ptr<BraveContentBrowserClient> browser_content_client_;
};

// Tests results of farbling known values
IN_PROC_BROWSER_TEST_F(BraveNavigatorHardwareConcurrencyFarblingBrowserTest,
FarbleNavigatorHardwareConcurrency) {
// Farbling level: off
// get real navigator.hardwareConcurrency
AllowFingerprinting();
NavigateToURLUntilLoadStop(farbling_url());
int real_value = ExecScriptGetInt(kHardwareConcurrencyScript, contents());
ASSERT_GE(real_value, 2);

// Farbling level: balanced (default)
// navigator.hardwareConcurrency should be greater than or equal to 2
// and less than or equal to the real value
SetFingerprintingDefault();
NavigateToURLUntilLoadStop(farbling_url());
int fake_value = ExecScriptGetInt(kHardwareConcurrencyScript, contents());
EXPECT_GE(fake_value, 2);
EXPECT_LE(fake_value, real_value);

// Farbling level: maximum
// navigator.hardwareConcurrency should be greater than or equal to 2
// and less than or equal to 8
BlockFingerprinting();
NavigateToURLUntilLoadStop(farbling_url());
int completely_fake_value =
ExecScriptGetInt(kHardwareConcurrencyScript, contents());
// For this domain (a.com) + the random seed (constant for browser tests),
// the value will always be the same.
EXPECT_EQ(completely_fake_value, 7);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* 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/. */

#include <random>

#include "base/system/sys_info.h"
#include "brave/third_party/blink/renderer/brave_farbling_constants.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/navigator_concurrent_hardware.h"

namespace brave {

using blink::LocalFrame;

const unsigned kFakeMinProcessors = 2;
const unsigned kFakeMaxProcessors = 8;

unsigned FarbleNumberOfProcessors(LocalFrame* frame) {
unsigned true_value =
static_cast<unsigned>(base::SysInfo::NumberOfProcessors());
if ((true_value <= 2) || !frame || !frame->GetContentSettingsClient())
return true_value;
unsigned farbled_value = true_value;
switch (frame->GetContentSettingsClient()->GetBraveFarblingLevel()) {
case BraveFarblingLevel::OFF: {
break;
}
case BraveFarblingLevel::MAXIMUM: {
true_value = kFakeMaxProcessors;
// "Maximum" behavior is "balanced" behavior but with a fake maximum,
// so fall through here.
U_FALLTHROUGH;
}
case BraveFarblingLevel::BALANCED: {
std::mt19937_64 prng = BraveSessionCache::From(*(frame->GetDocument()))
.MakePseudoRandomGenerator();
farbled_value =
kFakeMinProcessors + (prng() % (true_value + 1 - kFakeMinProcessors));
break;
}
default:
NOTREACHED();
}
return farbled_value;
}

} // namespace brave

namespace blink {

unsigned NavigatorConcurrentHardware::hardwareConcurrency(
ScriptState* script_state) const {
LocalFrame* frame = nullptr;
if (LocalDOMWindow* window = LocalDOMWindow::From(script_state))
frame = window->GetFrame();
return brave::FarbleNumberOfProcessors(frame);
}

} // namespace blink
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* 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_CORE_FRAME_NAVIGATOR_CONCURRENT_HARDWARE_H_
#define BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_CONCURRENT_HARDWARE_H_

#include "third_party/blink/renderer/core/core_export.h"

namespace blink {

class ScriptState;

class CORE_EXPORT NavigatorConcurrentHardware {
public:
unsigned hardwareConcurrency(ScriptState*) const;
};

} // namespace blink

#endif // BRAVE_CHROMIUM_SRC_THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_NAVIGATOR_CONCURRENT_HARDWARE_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
diff --git a/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl b/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl
index 3bb78d4b00c651a9edef3639a125736dc55d6be7..8bc1b636ba5423c443137aa7cb344261340de477 100644
--- a/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl
+++ b/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl
@@ -5,5 +5,5 @@
// https://html.spec.whatwg.org/C/#navigator.hardwareconcurrency

interface mixin NavigatorConcurrentHardware {
- [HighEntropy, MeasureAs=NavigatorHardwareConcurrency] readonly attribute unsigned long long hardwareConcurrency;
+ [CallWith=ScriptState, HighEntropy, MeasureAs=NavigatorHardwareConcurrency] readonly attribute unsigned long long hardwareConcurrency;
};
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ test("brave_browser_tests") {
"//brave/browser/extensions/brave_extension_functional_test.h",
"//brave/browser/extensions/brave_extension_provider_browsertest.cc",
"//brave/browser/extensions/brave_theme_event_router_browsertest.cc",
"//brave/browser/farbling/brave_navigator_hardwareconcurrency_farbling_browsertest.cc",
"//brave/browser/farbling/brave_navigator_plugins_farbling_browsertest.cc",
"//brave/browser/farbling/brave_offscreencanvas_farbling_browsertest.cc",
"//brave/browser/farbling/brave_webaudio_farbling_browsertest.cc",
Expand Down