fingerprinting-flags-client-rects-and-measuretext.patch 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. # Adds two flags:
  2. # 1. --fingerprinting-client-rects-noise to enable fingerprinting deception for Range::getClientRects and Element::getBoundingClientRect
  3. # 2. --fingerprinting-canvas-measuretext-noise to enable fingerprinting deception for Canvas::measureText
  4. # Tweaks based on https://github.com/bromite/bromite/blob/b1bc96bbd9ec549cf496e87f487a0ac35c83df0a/patches/BRM052_getClientRects-getBoundingClientRect-measureText-add-fingerprinting-mitigation.patch
  5. # Originally based on https://github.com/ungoogled-software/ungoogled-chromium/pull/377/commits/4151259b3248f0fc5c42fa262a1d1dd43c39fb60
  6. # chrome://flag setting added by ungoogled-chromium developers
  7. #
  8. # Unlike the latest Bromite patch, it was chosen to not regenerate the noise value each time the value is read to prevent potential efficiency issues with the load on the RNG.
  9. --- a/chrome/browser/BUILD.gn
  10. +++ b/chrome/browser/BUILD.gn
  11. @@ -2575,6 +2575,7 @@ static_library("browser") {
  12. "//third_party/libyuv",
  13. "//third_party/metrics_proto",
  14. "//third_party/re2",
  15. + "//components/ungoogled:ungoogled_switches",
  16. "//third_party/webrtc_overrides:webrtc_component",
  17. "//third_party/widevine/cdm:buildflags",
  18. "//third_party/widevine/cdm:headers",
  19. --- a/chrome/browser/about_flags.cc
  20. +++ b/chrome/browser/about_flags.cc
  21. @@ -167,6 +167,7 @@
  22. #include "components/translate/core/common/translate_util.h"
  23. #include "components/trusted_vault/features.h"
  24. #include "components/ui_devtools/switches.h"
  25. +#include "components/ungoogled/ungoogled_switches.h"
  26. #include "components/variations/variations_switches.h"
  27. #include "components/version_info/version_info.h"
  28. #include "components/viz/common/features.h"
  29. --- a/chrome/browser/bromite_flag_entries.h
  30. +++ b/chrome/browser/bromite_flag_entries.h
  31. @@ -4,4 +4,12 @@
  32. #ifndef CHROME_BROWSER_BROMITE_FLAG_ENTRIES_H_
  33. #define CHROME_BROWSER_BROMITE_FLAG_ENTRIES_H_
  34. + {"fingerprinting-client-rects-noise",
  35. + "Enable get*ClientRects() fingerprint deception",
  36. + "Scale the output values of Range::getClientRects() and Element::getBoundingClientRect() with a randomly selected factor in the range -0.0003% to 0.0003%, which are recomputed on every document initialization. ungoogled-chromium flag, Bromite feature.",
  37. + kOsAll, SINGLE_VALUE_TYPE(switches::kFingerprintingClientRectsNoise)},
  38. + {"fingerprinting-canvas-measuretext-noise",
  39. + "Enable Canvas::measureText() fingerprint deception",
  40. + "Scale the output values of Canvas::measureText() with a randomly selected factor in the range -0.0003% to 0.0003%, which are recomputed on every document initialization. ungoogled-chromium flag, Bromite feature.",
  41. + kOsAll, SINGLE_VALUE_TYPE(switches::kFingerprintingCanvasMeasureTextNoise)},
  42. #endif // CHROME_BROWSER_BROMITE_FLAG_ENTRIES_H_
  43. --- a/content/browser/BUILD.gn
  44. +++ b/content/browser/BUILD.gn
  45. @@ -247,6 +247,7 @@ source_set("browser") {
  46. "//third_party/libyuv",
  47. "//third_party/re2",
  48. "//third_party/sqlite",
  49. + "//components/ungoogled:ungoogled_switches",
  50. "//third_party/webrtc_overrides:webrtc_component",
  51. "//third_party/zlib",
  52. "//third_party/zlib/google:zip",
  53. --- a/content/browser/renderer_host/render_process_host_impl.cc
  54. +++ b/content/browser/renderer_host/render_process_host_impl.cc
  55. @@ -77,6 +77,7 @@
  56. #include "components/services/storage/public/cpp/quota_error_or.h"
  57. #include "components/services/storage/public/mojom/cache_storage_control.mojom.h"
  58. #include "components/tracing/common/tracing_switches.h"
  59. +#include "components/ungoogled/ungoogled_switches.h"
  60. #include "components/viz/common/switches.h"
  61. #include "components/viz/host/gpu_client.h"
  62. #include "content/browser/bad_message.h"
  63. @@ -3420,6 +3421,8 @@ void RenderProcessHostImpl::PropagateBro
  64. switches::kEnableWebGLImageChromium,
  65. switches::kEnableWebGPUDeveloperFeatures,
  66. switches::kFileUrlPathAlias,
  67. + switches::kFingerprintingClientRectsNoise,
  68. + switches::kFingerprintingCanvasMeasureTextNoise,
  69. switches::kForceDeviceScaleFactor,
  70. switches::kForceDisplayColorProfile,
  71. switches::kForceGpuMemAvailableMb,
  72. --- a/content/child/BUILD.gn
  73. +++ b/content/child/BUILD.gn
  74. @@ -103,6 +103,7 @@ target(link_target_type, "child") {
  75. "//third_party/blink/public/common:buildflags",
  76. "//third_party/blink/public/strings",
  77. "//third_party/ced",
  78. + "//components/ungoogled:ungoogled_switches",
  79. "//third_party/zlib/google:compression_utils",
  80. "//ui/base",
  81. "//ui/events/blink",
  82. --- a/content/child/runtime_features.cc
  83. +++ b/content/child/runtime_features.cc
  84. @@ -40,6 +40,7 @@
  85. #include "third_party/blink/public/common/loader/referrer_utils.h"
  86. #include "third_party/blink/public/common/switches.h"
  87. #include "third_party/blink/public/platform/web_runtime_features.h"
  88. +#include "components/ungoogled/ungoogled_switches.h"
  89. #include "ui/accessibility/accessibility_features.h"
  90. #include "ui/base/ui_base_features.h"
  91. #include "ui/events/blink/blink_features.h"
  92. @@ -475,6 +476,10 @@ void SetRuntimeFeaturesFromCommandLine(c
  93. switches::kEnableWebGPUDeveloperFeatures, true},
  94. {wrf::EnableDirectSockets, switches::kEnableIsolatedWebAppsInRenderer,
  95. true},
  96. + {wrf::EnableFingerprintingClientRectsNoise,
  97. + switches::kFingerprintingClientRectsNoise, true},
  98. + {wrf::EnableFingerprintingCanvasMeasureTextNoise,
  99. + switches::kFingerprintingCanvasMeasureTextNoise, true},
  100. };
  101. for (const auto& mapping : switchToFeatureMapping) {
  102. --- a/third_party/blink/public/platform/web_runtime_features.h
  103. +++ b/third_party/blink/public/platform/web_runtime_features.h
  104. @@ -69,6 +69,9 @@ class BLINK_PLATFORM_EXPORT WebRuntimeFe
  105. static void EnableFluentScrollbars(bool);
  106. static void EnableFluentOverlayScrollbars(bool);
  107. + static void EnableFingerprintingClientRectsNoise(bool);
  108. + static void EnableFingerprintingCanvasMeasureTextNoise(bool);
  109. +
  110. WebRuntimeFeatures() = delete;
  111. };
  112. --- a/third_party/blink/renderer/core/dom/document.cc
  113. +++ b/third_party/blink/renderer/core/dom/document.cc
  114. @@ -39,6 +39,7 @@
  115. #include "base/i18n/time_formatting.h"
  116. #include "base/metrics/histogram_functions.h"
  117. #include "base/notreached.h"
  118. +#include "base/rand_util.h"
  119. #include "base/ranges/algorithm.h"
  120. #include "base/task/single_thread_task_runner.h"
  121. #include "base/time/time.h"
  122. @@ -943,6 +944,14 @@ Range* Document::CreateRangeAdjustedToTr
  123. Position::BeforeNode(*shadow_host));
  124. }
  125. +double Document::GetNoiseFactorX() {
  126. + return noise_factor_x_;
  127. +}
  128. +
  129. +double Document::GetNoiseFactorY() {
  130. + return noise_factor_y_;
  131. +}
  132. +
  133. SelectorQueryCache& Document::GetSelectorQueryCache() {
  134. if (!selector_query_cache_)
  135. selector_query_cache_ = std::make_unique<SelectorQueryCache>();
  136. @@ -2318,6 +2327,15 @@ void Document::UpdateStyleAndLayoutTreeF
  137. #if DCHECK_IS_ON()
  138. AssertLayoutTreeUpdated(*this, true /* allow_dirty_container_subtrees */);
  139. #endif
  140. +
  141. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  142. + // Precompute -0.0003% to 0.0003% noise factor for get*ClientRect*() fingerprinting
  143. + noise_factor_x_ = 1 + (base::RandDouble() - 0.5) * 0.000003;
  144. + noise_factor_y_ = 1 + (base::RandDouble() - 0.5) * 0.000003;
  145. + } else {
  146. + noise_factor_x_ = 1;
  147. + noise_factor_y_ = 1;
  148. + }
  149. }
  150. void Document::InvalidateStyleAndLayoutForFontUpdates() {
  151. --- a/third_party/blink/renderer/core/dom/document.h
  152. +++ b/third_party/blink/renderer/core/dom/document.h
  153. @@ -511,6 +511,10 @@ class CORE_EXPORT Document : public Cont
  154. has_xml_declaration_ = has_xml_declaration ? 1 : 0;
  155. }
  156. + // Values for get*ClientRect fingerprint deception
  157. + double GetNoiseFactorX();
  158. + double GetNoiseFactorY();
  159. +
  160. AtomicString visibilityState() const;
  161. bool IsPageVisible() const;
  162. bool hidden() const;
  163. @@ -2413,6 +2417,9 @@ class CORE_EXPORT Document : public Cont
  164. base::ElapsedTimer start_time_;
  165. + double noise_factor_x_;
  166. + double noise_factor_y_;
  167. +
  168. Member<ScriptRunner> script_runner_;
  169. Member<ScriptRunnerDelayer> script_runner_delayer_;
  170. --- a/third_party/blink/renderer/core/dom/element.cc
  171. +++ b/third_party/blink/renderer/core/dom/element.cc
  172. @@ -2123,6 +2123,11 @@ DOMRectList* Element::getClientRects() {
  173. DCHECK(element_layout_object);
  174. GetDocument().AdjustQuadsForScrollAndAbsoluteZoom(quads,
  175. *element_layout_object);
  176. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  177. + for (gfx::QuadF& quad : quads) {
  178. + quad.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
  179. + }
  180. + }
  181. return MakeGarbageCollected<DOMRectList>(quads);
  182. }
  183. @@ -2150,6 +2155,9 @@ gfx::RectF Element::GetBoundingClientRec
  184. DCHECK(element_layout_object);
  185. GetDocument().AdjustRectForScrollAndAbsoluteZoom(result,
  186. *element_layout_object);
  187. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  188. + result.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
  189. + }
  190. return result;
  191. }
  192. --- a/third_party/blink/renderer/core/dom/range.cc
  193. +++ b/third_party/blink/renderer/core/dom/range.cc
  194. @@ -1618,11 +1618,21 @@ DOMRectList* Range::getClientRects() con
  195. Vector<gfx::QuadF> quads;
  196. GetBorderAndTextQuads(quads);
  197. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  198. + for (gfx::QuadF& quad : quads) {
  199. + quad.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
  200. + }
  201. + }
  202. +
  203. return MakeGarbageCollected<DOMRectList>(quads);
  204. }
  205. DOMRect* Range::getBoundingClientRect() const {
  206. - return DOMRect::FromRectF(BoundingRect());
  207. + auto rect = BoundingRect();
  208. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  209. + rect.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
  210. + }
  211. + return DOMRect::FromRectF(rect);
  212. }
  213. // TODO(editing-dev): We should make
  214. --- a/third_party/blink/renderer/core/html/canvas/text_metrics.cc
  215. +++ b/third_party/blink/renderer/core/html/canvas/text_metrics.cc
  216. @@ -69,6 +69,24 @@ TextMetrics::TextMetrics(const Font& fon
  217. Update(font, direction, baseline, align, text);
  218. }
  219. +void TextMetrics::Shuffle(const double factor) {
  220. + // x-direction
  221. + width_ *= factor;
  222. + actual_bounding_box_left_ *= factor;
  223. + actual_bounding_box_right_ *= factor;
  224. +
  225. + // y-direction
  226. + font_bounding_box_ascent_ *= factor;
  227. + font_bounding_box_descent_ *= factor;
  228. + actual_bounding_box_ascent_ *= factor;
  229. + actual_bounding_box_descent_ *= factor;
  230. + em_height_ascent_ *= factor;
  231. + em_height_descent_ *= factor;
  232. + baselines_->setAlphabetic(baselines_->alphabetic() * factor);
  233. + baselines_->setHanging(baselines_->hanging() * factor);
  234. + baselines_->setIdeographic(baselines_->ideographic() * factor);
  235. +}
  236. +
  237. void TextMetrics::Update(const Font& font,
  238. const TextDirection& direction,
  239. const TextBaseline& baseline,
  240. --- a/third_party/blink/renderer/core/html/canvas/text_metrics.h
  241. +++ b/third_party/blink/renderer/core/html/canvas/text_metrics.h
  242. @@ -66,6 +66,8 @@ class CORE_EXPORT TextMetrics final : pu
  243. void Trace(Visitor*) const override;
  244. + void Shuffle(const double factor);
  245. +
  246. private:
  247. void Update(const Font&,
  248. const TextDirection&,
  249. --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
  250. +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
  251. @@ -56,6 +56,9 @@
  252. #include "ui/gfx/geometry/quad_f.h"
  253. #include "ui/gfx/geometry/skia_conversions.h"
  254. +#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
  255. +#include "third_party/blink/renderer/core/frame/local_dom_window.h"
  256. +
  257. namespace blink {
  258. BASE_FEATURE(kDisableCanvasOverdrawOptimization,
  259. @@ -2892,9 +2895,22 @@ TextMetrics* BaseRenderingContext2D::mea
  260. TextDirection direction = ToTextDirection(GetState().GetDirection(), canvas);
  261. - return MakeGarbageCollected<TextMetrics>(font, direction,
  262. + TextMetrics* text_metrics = MakeGarbageCollected<TextMetrics>(font, direction,
  263. GetState().GetTextBaseline(),
  264. GetState().GetTextAlign(), text);
  265. +
  266. + // Scale text metrics if enabled
  267. + if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled()) {
  268. + if (HostAsOffscreenCanvas()) {
  269. + if (auto* window = DynamicTo<LocalDOMWindow>(GetTopExecutionContext())) {
  270. + if (window->GetFrame() && window->GetFrame()->GetDocument())
  271. + text_metrics->Shuffle(window->GetFrame()->GetDocument()->GetNoiseFactorX());
  272. + }
  273. + } else if (canvas) {
  274. + text_metrics->Shuffle(canvas->GetDocument().GetNoiseFactorX());
  275. + }
  276. + }
  277. + return text_metrics;
  278. }
  279. void BaseRenderingContext2D::SnapshotStateForFilter() {
  280. --- a/third_party/blink/renderer/platform/BUILD.gn
  281. +++ b/third_party/blink/renderer/platform/BUILD.gn
  282. @@ -1702,6 +1702,7 @@ component("platform") {
  283. "//cc/mojo_embedder",
  284. "//components/paint_preview/common",
  285. "//components/search_engines:search_engine_utils",
  286. + "//components/ungoogled:ungoogled_switches",
  287. "//components/viz/client",
  288. "//components/viz/common",
  289. "//components/webrtc:net_address_utils",
  290. --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
  291. +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
  292. @@ -68,4 +68,12 @@ void WebRuntimeFeatures::EnableFluentScr
  293. void WebRuntimeFeatures::EnableFluentOverlayScrollbars(bool enable) {
  294. RuntimeEnabledFeatures::SetFluentOverlayScrollbarsEnabled(enable);
  295. }
  296. +void WebRuntimeFeatures::EnableFingerprintingClientRectsNoise(bool enable) {
  297. + RuntimeEnabledFeatures::SetFingerprintingClientRectsNoiseEnabled(enable);
  298. +}
  299. +
  300. +void WebRuntimeFeatures::EnableFingerprintingCanvasMeasureTextNoise(bool enable) {
  301. + RuntimeEnabledFeatures::SetFingerprintingCanvasMeasureTextNoiseEnabled(enable);
  302. +}
  303. +
  304. } // namespace blink
  305. --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
  306. +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
  307. @@ -1887,6 +1887,12 @@
  308. origin_trial_feature_name: "Focusgroup",
  309. },
  310. {
  311. + name: "FingerprintingClientRectsNoise",
  312. + },
  313. + {
  314. + name: "FingerprintingCanvasMeasureTextNoise",
  315. + },
  316. + {
  317. name: "FocuslessSpatialNavigation",
  318. base_feature: "none",
  319. settable_from_internals: true,