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

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

Closed
arthuredelstein opened this issue Aug 15, 2022 · 14 comments · Fixed by brave/brave-core#15309

Comments

@arthuredelstein
Copy link

arthuredelstein commented Aug 15, 2022

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

@arthuredelstein arthuredelstein added OS/Android Fixes related to Android browser functionality OS/Desktop labels Aug 15, 2022
@arthuredelstein
Copy link
Author

cc: @diracdeltas @pes10k

@arthuredelstein arthuredelstein self-assigned this Aug 15, 2022
@arthuredelstein
Copy link
Author

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.)

@arthuredelstein
Copy link
Author

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.

@diracdeltas diracdeltas changed the title performance.now and other timing APIs are fingerprinting vectors [hackerone] performance.now and other timing APIs are fingerprinting vectors Aug 22, 2022
@brave-builds brave-builds added this to the 1.47.x - Nightly milestone Oct 20, 2022
@LaurenWags
Copy link
Member

@arthuredelstein @diracdeltas

  1. Since this is labelled as QA/Yes, we will need a manual test plan. [hackerone] performance.now and other timing APIs are fingerprinting vectors #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

@pes10k
Copy link
Contributor

pes10k commented Dec 2, 2022

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

@pes10k
Copy link
Contributor

pes10k commented Dec 2, 2022

https://dev-pages.brave.software/dom-properties/performance.html

@kjozwiak
Copy link
Member

kjozwiak commented Dec 6, 2022

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 👍

@GeetaSarvadnya
Copy link

GeetaSarvadnya commented Dec 14, 2022

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

@MadhaviSeelam
Copy link

MadhaviSeelam commented Dec 15, 2022

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

@stephendonner
Copy link

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

@Uni-verse
Copy link
Contributor

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

@jdknox
Copy link

jdknox commented Mar 21, 2023

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?

@pes10k
Copy link
Contributor

pes10k commented Mar 21, 2023

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?

@abrahamjuliot
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment