brave / brave-browser

Brave browser for Android, iOS, Linux, macOS, Windows.

Home Page:https://brave.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[hackerone] performance.now and other timing APIs are fingerprinting vectors

arthuredelstein opened this issue · comments

Description

From joe12387:

performance.now() can be used to create a persistent cross-site tracking fingerprint...

This code allows you to track a user from site to site, it does not detect if a user is using Brave. My fingerprint is [0.09999990463256836, 0.10000014305114746], while other machines will have a different value.

This is very easy to fix, all you have to do is round the output of performance.now() into an integer and the script will always return [1,1].

Steps to Reproduce

See https://github.com/Joe12387/OP-Fingerprinting-Script/blob/b4b196f5a6196bacf2dc041b064f877dafafface/opfs.js#L443

See also: #2952

What I have learned so far:
performance.now() and related high-resolution timers are clamped to 100-us resolution in Chrome EXCEPT where

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

in which case the timing values are clamped to 5-us resolution.

These two resolutions are specified in Chrome by two constants:

static constexpr int kCoarseResolutionMicroseconds = 100;
static constexpr int kFineResolutionMicroseconds = 5;

(These constants are used in only two places in the source code currently.)

The plan is:

  1. When shields are up, we will apply 1000-us rounding to all high-resolution timers, regardless of header values.
  2. When shields are down, we revert to the Chrome behavior in the previous comment.

@arthuredelstein @diracdeltas

  1. Since this is labelled as QA/Yes, we will need a manual test plan. #24681 (comment) links to some code that isn't clear to me what I need to do in order to test this one. Labelling as QA/Blocked until we have this.
  2. Does this issue need the security label?

cc @kjozwiak @rebron

I'll create a test for this one. Should be done in an hour or so

Removed the QA/Blocked as @pes10k created a test under https://dev-pages.brave.software/dom-properties/performance.html as per #24681 (comment).

Going to add the security label as well. @pes10k @arthuredelstein if you feel different, please remove 👍

cc: @arthuredelstein

Verified the issue in Windows 10 x64 - 1.47.126 Chromium: 108.0.5359.99

Verified the test instructions from https://dev-pages.brave.software/dom-properties/performance.html

When Shields are down, they should be a mix of integers and float values.

I am not getting the mix of integers and float values when shields are down
image

Verification PASSED using

Brave | 1.47.129 Chromium: 108.0.5359.128 (Official Build) beta (64-bit)
-- | --
Revision | 1cd27afdb8e5d057070c0961e04c490d2aca1aa0-refs/branch-heads/5359@{#1185}
OS | Windows 11 Version 21H2 (Build 22000.1335)

Steps:

  • Install 1.47.129
  • launch Brave

Case 1: Enable #brave-round-time-stamps feature flag

  1. open brave://flags
  2. set to Enabled for #brave-round-time-stamps
  3. click Relaunch Brave
  4. visit https://dev-pages.bravesoftware.com/dom-properties/performance.html in a new-tab
  5. toggle Off Shields toggle
  6. click Run test button

Confirmed integers returned as expected.

step 2 step 5 result
image image image

Case 2: Disable #brave-round-time-stamps feature flag

  1. open brave://flags
  2. set to Disabled for #brave-round-time-stamps
  3. click Relaunch Brave
  4. visit https://dev-pages.bravesoftware.com/dom-properties/performance.html in a new-tab
  5. toggle Off Shields
  6. click Run test button

Confirmed integers & float values returned as expected since the flag is disabled

step 2 step 5 result result
image image image image

*Note: The wording on the buttons show Test failed is incorrect. Should have been Test Succeeded. Confirmed with @arthuredelstein and above tests are correct.
https://bravesoftware.slack.com/archives/C7VLGSR55/p1671119340076209?thread_ts=1671036126.362999&cid=C7VLGSR55

Verified PASSED using

Brave 1.47.135 Chromium: 108.0.5359.128 (Official Build) beta (x86_64)
Revision 1cd27afdb8e5d057070c0961e04c490d2aca1aa0-refs/branch-heads/5359@{#1185}
OS macOS Version 11.7.2 (Build 20G1020)

Case 1: Enable #brave-round-time-stamps feature flag

  1. installed 1.47.135
  2. opened brave://flags
  3. set Enabled for #brave-round-time-stamps
  4. clicked Relaunch button
  5. loaded https://dev-pages.bravesoftware.com/dom-properties/performance.html in a new tab
  6. toggled Shields Off
  7. clicked Run test button

Confirmed all integers returned were rounded

brave://flags Test succeeded
Screen Shot 2022-12-19 at 7 18 49 PM Screen Shot 2022-12-19 at 7 18 58 PM

Case 2: Disable #brave-round-time-stamps feature flags

  1. installed 1.47.135
  2. opened brave://flags
  3. set Disabled for #brave-round-time-stamps
  4. clicked on Relaunch
  5. loaded https://dev-pages.bravesoftware.com/dom-properties/performance.html in a new tab
  6. toggled Shields to Off
  7. clicked Run test button

Confirmed integers & float values returned as expected since the flag is disabled

brave://flags Output - "Test failed"
Screen Shot 2022-12-19 at 8 54 44 PM Screen Shot 2022-12-19 at 8 54 52 PM

*Note: The wording on the buttons show Test failed is incorrect. Should have been Test Succeeded. Confirmed with @arthuredelstein and above tests are correct.
https://bravesoftware.slack.com/archives/C7VLGSR55/p1671119340076209?thread_ts=1671036126.362999&cid=C7VLGSR55

Verified on Samsung Galaxy S21 running Android 12 using version:

Brave	1.47.165 Chromium: 109.0.5414.80 (Official Build) (64-bit) 
Revision	0f69b168d36a06cace4365e9f029fa987afa5633-refs/branch-heads/5414@{#1178}
OS	Android 12; Build/SP1A.210812.016

Case: Flag enabled

  1. Enabled for brave://flags#brave-round-time-stamps
  2. Open test page - https://dev-pages.bravesoftware.com/dom-properties/performance.html
  3. Disable Shields
  4. Run Test
  • Ensured that test results for all frames show as test succeeded and all values are integers
Shields ON Shields OFF Feature Flag
screenshot-1673281991099 screenshot-1673281964790 screenshot-1673282072477

Case: Flag disabled

  1. Enabled for brave://flags#brave-round-time-stamps
  2. Open test page - https://dev-pages.bravesoftware.com/dom-properties/performance.html
  3. Disable Shields
  4. Run Test
  • Ensured that tests fail and values are mix of integers and floats when brave://flags#brave-round-time-stamps is disabled
Feature Flag Performance Test
screenshot-1673282106528 screenshot-1673282122710
commented

Description

From joe12387:

performance.now() can be used to create a persistent cross-site tracking fingerprint...

This code allows you to track a user from site to site, it does not detect if a user is using Brave. My fingerprint is [0.09999990463256836, 0.10000014305114746], while other machines will have a different value.

I just want to note that I get the exact same values as the fingerprint results above:

...

> [valueA, valueB]
(2) [0.09999990463256836, 0.10000014305114746]
> valueA - 0.09999990463256836
0
> valueB - 0.10000014305114746
0

Is this actually a useful fingerprinting technique if the values are the same across machines?

commented

I believe you're getting the same values because of the changes in this PR. Or are you testing in different browsers? Am i misunderstanding?

If you restart your machine or device, it should change.