Skip to content

Commit

Permalink
Implement navigator.hardwareConcurrency farbling
Browse files Browse the repository at this point in the history
lint

.

tests

patch IDL instead

.

lint

.

.
  • Loading branch information
pilgrim-brave committed Aug 13, 2020
1 parent 33b40bd commit 9f6deda
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
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

0 comments on commit 9f6deda

Please sign in to comment.