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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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/Eloston/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. @@ -2272,6 +2272,7 @@ jumbo_static_library("browser") {
  12. "//third_party/libyuv",
  13. "//third_party/metrics_proto",
  14. "//third_party/re2",
  15. + "//components/ungoogled:switches",
  16. "//third_party/webrtc_overrides:webrtc_component",
  17. "//third_party/widevine/cdm:buildflags",
  18. "//third_party/zlib",
  19. --- a/chrome/browser/about_flags.cc
  20. +++ b/chrome/browser/about_flags.cc
  21. @@ -157,6 +157,7 @@
  22. #include "third_party/blink/public/common/features.h"
  23. #include "third_party/blink/public/common/forcedark/forcedark_switches.h"
  24. #include "third_party/leveldatabase/leveldb_features.h"
  25. +#include "components/ungoogled/ungoogled_switches.h"
  26. #include "ui/accessibility/accessibility_features.h"
  27. #include "ui/accessibility/accessibility_switches.h"
  28. #include "ui/base/ui_base_features.h"
  29. @@ -1801,6 +1802,14 @@ const FeatureEntry kFeatureEntries[] = {
  30. "Force punycode hostnames",
  31. "Force punycode in hostnames instead of Unicode when displaying Internationalized Domain Names (IDNs).",
  32. kOsAll, SINGLE_VALUE_TYPE("force-punycode-hostnames")},
  33. + {"fingerprinting-client-rects-noise",
  34. + "Enable get*ClientRects() fingerprint deception",
  35. + "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.",
  36. + kOsAll, SINGLE_VALUE_TYPE(switches::kFingerprintingClientRectsNoise)},
  37. + {"fingerprinting-canvas-measuretext-noise",
  38. + "Enable Canvas::measureText() fingerprint deception",
  39. + "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.",
  40. + kOsAll, SINGLE_VALUE_TYPE(switches::kFingerprintingCanvasMeasureTextNoise)},
  41. {"ignore-gpu-blacklist", flag_descriptions::kIgnoreGpuBlacklistName,
  42. flag_descriptions::kIgnoreGpuBlacklistDescription, kOsAll,
  43. SINGLE_VALUE_TYPE(switches::kIgnoreGpuBlacklist)},
  44. --- a/content/browser/BUILD.gn
  45. +++ b/content/browser/BUILD.gn
  46. @@ -208,6 +208,7 @@ jumbo_source_set("browser") {
  47. "//third_party/libyuv",
  48. "//third_party/re2",
  49. "//third_party/sqlite",
  50. + "//components/ungoogled:switches",
  51. "//third_party/webrtc_overrides:webrtc_component",
  52. "//third_party/zlib",
  53. "//third_party/zlib/google:zip",
  54. --- a/content/browser/renderer_host/render_process_host_impl.cc
  55. +++ b/content/browser/renderer_host/render_process_host_impl.cc
  56. @@ -225,6 +225,7 @@
  57. #include "third_party/blink/public/common/page/launching_process_state.h"
  58. #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
  59. #include "third_party/blink/public/public_buildflags.h"
  60. +#include "components/ungoogled/ungoogled_switches.h"
  61. #include "third_party/skia/include/core/SkBitmap.h"
  62. #include "ui/accessibility/accessibility_switches.h"
  63. #include "ui/base/ui_base_switches.h"
  64. @@ -3279,6 +3280,8 @@ void RenderProcessHostImpl::PropagateBro
  65. switches::kEnableWebGLDraftExtensions,
  66. switches::kEnableWebGLImageChromium,
  67. switches::kFileUrlPathAlias,
  68. + switches::kFingerprintingClientRectsNoise,
  69. + switches::kFingerprintingCanvasMeasureTextNoise,
  70. switches::kForceDeviceScaleFactor,
  71. switches::kForceDisableWebRtcApmInAudioService,
  72. switches::kForceDisplayColorProfile,
  73. --- a/content/child/BUILD.gn
  74. +++ b/content/child/BUILD.gn
  75. @@ -123,6 +123,7 @@ target(link_target_type, "child") {
  76. "//third_party/blink/public/common",
  77. "//third_party/blink/public/strings",
  78. "//third_party/ced",
  79. + "//components/ungoogled:switches",
  80. "//third_party/zlib/google:compression_utils",
  81. "//ui/base",
  82. "//ui/events/blink",
  83. --- a/content/child/runtime_features.cc
  84. +++ b/content/child/runtime_features.cc
  85. @@ -26,6 +26,7 @@
  86. #include "services/network/public/cpp/network_switches.h"
  87. #include "third_party/blink/public/common/features.h"
  88. #include "third_party/blink/public/platform/web_runtime_features.h"
  89. +#include "components/ungoogled/ungoogled_switches.h"
  90. #include "ui/accessibility/accessibility_features.h"
  91. #include "ui/base/ui_base_features.h"
  92. #include "ui/events/blink/blink_features.h"
  93. @@ -449,6 +450,10 @@ void SetRuntimeFeaturesFromCommandLine(c
  94. switches::kEnableAccessibilityObjectModel, true},
  95. {wrf::EnableAllowSyncXHRInPageDismissal,
  96. switches::kAllowSyncXHRInPageDismissal, true},
  97. + {wrf::EnableFingerprintingClientRectsNoise,
  98. + switches::kFingerprintingClientRectsNoise, true},
  99. + {wrf::EnableFingerprintingCanvasMeasureTextNoise,
  100. + switches::kFingerprintingCanvasMeasureTextNoise, true},
  101. {wrf::EnableShadowDOMV0, switches::kWebComponentsV0Enabled, true},
  102. {wrf::EnableCustomElementsV0, switches::kWebComponentsV0Enabled, true},
  103. {wrf::EnableHTMLImports, switches::kWebComponentsV0Enabled, true},
  104. --- a/third_party/blink/public/platform/web_runtime_features.h
  105. +++ b/third_party/blink/public/platform/web_runtime_features.h
  106. @@ -220,6 +220,8 @@ class WebRuntimeFeatures {
  107. BLINK_PLATFORM_EXPORT static void EnableTranslateService(bool);
  108. BLINK_PLATFORM_EXPORT static void EnableGetDisplayMedia(bool);
  109. BLINK_PLATFORM_EXPORT static void EnableAllowSyncXHRInPageDismissal(bool);
  110. + BLINK_PLATFORM_EXPORT static void EnableFingerprintingClientRectsNoise(bool);
  111. + BLINK_PLATFORM_EXPORT static void EnableFingerprintingCanvasMeasureTextNoise(bool);
  112. BLINK_PLATFORM_EXPORT static void EnableShadowDOMV0(bool);
  113. BLINK_PLATFORM_EXPORT static void EnableCustomElementsV0(bool);
  114. BLINK_PLATFORM_EXPORT static void EnableHTMLImports(bool);
  115. --- a/third_party/blink/renderer/core/dom/document.cc
  116. +++ b/third_party/blink/renderer/core/dom/document.cc
  117. @@ -35,6 +35,7 @@
  118. #include "base/auto_reset.h"
  119. #include "base/macros.h"
  120. #include "base/optional.h"
  121. +#include "base/rand_util.h"
  122. #include "base/time/time.h"
  123. #include "cc/input/overscroll_behavior.h"
  124. #include "cc/input/scroll_snap_data.h"
  125. @@ -883,6 +884,14 @@ Range* Document::CreateRangeAdjustedToTr
  126. Position::BeforeNode(*shadow_host));
  127. }
  128. +double Document::GetNoiseFactorX() {
  129. + return noise_factor_x_;
  130. +}
  131. +
  132. +double Document::GetNoiseFactorY() {
  133. + return noise_factor_y_;
  134. +}
  135. +
  136. SelectorQueryCache& Document::GetSelectorQueryCache() {
  137. if (!selector_query_cache_)
  138. selector_query_cache_ = std::make_unique<SelectorQueryCache>();
  139. @@ -2628,6 +2637,15 @@ void Document::UpdateStyleAndLayoutTree(
  140. #if DCHECK_IS_ON()
  141. AssertLayoutTreeUpdated(*this);
  142. #endif
  143. +
  144. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  145. + // Precompute -0.0003% to 0.0003% noise factor for get*ClientRect*() fingerprinting
  146. + noise_factor_x_ = 1 + (base::RandDouble() - 0.5) * 0.000003;
  147. + noise_factor_y_ = 1 + (base::RandDouble() - 0.5) * 0.000003;
  148. + } else {
  149. + noise_factor_x_ = 1;
  150. + noise_factor_y_ = 1;
  151. + }
  152. }
  153. void Document::UpdateActiveStyle() {
  154. --- a/third_party/blink/renderer/core/dom/document.h
  155. +++ b/third_party/blink/renderer/core/dom/document.h
  156. @@ -534,6 +534,10 @@ class CORE_EXPORT Document : public Cont
  157. has_xml_declaration_ = has_xml_declaration ? 1 : 0;
  158. }
  159. + // Values for get*ClientRect fingerprint deception
  160. + double GetNoiseFactorX();
  161. + double GetNoiseFactorY();
  162. +
  163. String visibilityState() const;
  164. bool IsPageVisible() const;
  165. bool hidden() const;
  166. @@ -2106,6 +2110,9 @@ class CORE_EXPORT Document : public Cont
  167. base::ElapsedTimer start_time_;
  168. + double noise_factor_x_;
  169. + double noise_factor_y_;
  170. +
  171. Member<ScriptRunner> script_runner_;
  172. HeapVector<Member<ScriptElementBase>> current_script_stack_;
  173. --- a/third_party/blink/renderer/core/dom/element.cc
  174. +++ b/third_party/blink/renderer/core/dom/element.cc
  175. @@ -1985,6 +1985,11 @@ DOMRectList* Element::getClientRects() {
  176. DCHECK(element_layout_object);
  177. GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom(
  178. quads, *element_layout_object);
  179. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  180. + for (FloatQuad& quad : quads) {
  181. + quad.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
  182. + }
  183. + }
  184. return MakeGarbageCollected<DOMRectList>(quads);
  185. }
  186. @@ -2002,6 +2007,9 @@ DOMRect* Element::getBoundingClientRect(
  187. DCHECK(element_layout_object);
  188. GetDocument().AdjustFloatRectForScrollAndAbsoluteZoom(result,
  189. *element_layout_object);
  190. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  191. + result.Scale(GetDocument().GetNoiseFactorX(), GetDocument().GetNoiseFactorY());
  192. + }
  193. return DOMRect::FromFloatRect(result);
  194. }
  195. --- a/third_party/blink/renderer/core/dom/range.cc
  196. +++ b/third_party/blink/renderer/core/dom/range.cc
  197. @@ -1614,11 +1614,21 @@ DOMRectList* Range::getClientRects() con
  198. Vector<FloatQuad> quads;
  199. GetBorderAndTextQuads(quads);
  200. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  201. + for (FloatQuad& quad : quads) {
  202. + quad.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
  203. + }
  204. + }
  205. +
  206. return MakeGarbageCollected<DOMRectList>(quads);
  207. }
  208. DOMRect* Range::getBoundingClientRect() const {
  209. - return DOMRect::FromFloatRect(BoundingRect());
  210. + auto rect = BoundingRect();
  211. + if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
  212. + rect.Scale(owner_document_->GetNoiseFactorX(), owner_document_->GetNoiseFactorY());
  213. + }
  214. + return DOMRect::FromFloatRect(rect);
  215. }
  216. // TODO(editing-dev): We should make
  217. --- a/third_party/blink/renderer/core/html/canvas/text_metrics.cc
  218. +++ b/third_party/blink/renderer/core/html/canvas/text_metrics.cc
  219. @@ -54,6 +54,24 @@ TextMetrics::TextMetrics(const Font& fon
  220. Update(font, direction, baseline, align, text);
  221. }
  222. +void TextMetrics::Shuffle(const double factor) {
  223. + // x-direction
  224. + width_ *= factor;
  225. + actual_bounding_box_left_ *= factor;
  226. + actual_bounding_box_right_ *= factor;
  227. +
  228. + // y-direction
  229. + font_bounding_box_ascent_ *= factor;
  230. + font_bounding_box_descent_ *= factor;
  231. + actual_bounding_box_ascent_ *= factor;
  232. + actual_bounding_box_descent_ *= factor;
  233. + em_height_ascent_ *= factor;
  234. + em_height_descent_ *= factor;
  235. + baselines_->setAlphabetic(baselines_->alphabetic() * factor);
  236. + baselines_->setHanging(baselines_->hanging() * factor);
  237. + baselines_->setIdeographic(baselines_->ideographic() * factor);
  238. +}
  239. +
  240. void TextMetrics::Update(const Font& font,
  241. const TextDirection& direction,
  242. const TextBaseline& baseline,
  243. --- a/third_party/blink/renderer/core/html/canvas/text_metrics.h
  244. +++ b/third_party/blink/renderer/core/html/canvas/text_metrics.h
  245. @@ -64,6 +64,8 @@ class CORE_EXPORT TextMetrics final : pu
  246. void Trace(Visitor*) override;
  247. + void Shuffle(const double factor);
  248. +
  249. private:
  250. void Update(const Font&,
  251. const TextDirection&,
  252. --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
  253. +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
  254. @@ -815,9 +815,15 @@ TextMetrics* CanvasRenderingContext2D::m
  255. else
  256. direction = ToTextDirection(GetState().GetDirection(), canvas());
  257. - return MakeGarbageCollected<TextMetrics>(font, direction,
  258. + TextMetrics* text_metrics = MakeGarbageCollected<TextMetrics>(font, direction,
  259. GetState().GetTextBaseline(),
  260. GetState().GetTextAlign(), text);
  261. +
  262. + // Scale text metrics if enabled
  263. + if (RuntimeEnabledFeatures::FingerprintingCanvasMeasureTextNoiseEnabled()) {
  264. + text_metrics->Shuffle(canvas()->GetDocument().GetNoiseFactorX());
  265. + }
  266. + return text_metrics;
  267. }
  268. void CanvasRenderingContext2D::DrawTextInternal(
  269. --- a/third_party/blink/renderer/platform/BUILD.gn
  270. +++ b/third_party/blink/renderer/platform/BUILD.gn
  271. @@ -1543,6 +1543,7 @@ jumbo_component("platform") {
  272. "//third_party/harfbuzz-ng:hb_scoped_util",
  273. "//third_party/icu",
  274. "//third_party/libyuv",
  275. + "//components/ungoogled:switches",
  276. "//third_party/webrtc_overrides:webrtc_component",
  277. "//third_party/zlib/google:compression_utils",
  278. "//ui/base/cursor",
  279. --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
  280. +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
  281. @@ -667,4 +667,12 @@ void WebRuntimeFeatures::EnableTrustToke
  282. RuntimeEnabledFeatures::SetTrustTokensEnabled(enable);
  283. }
  284. +void WebRuntimeFeatures::EnableFingerprintingClientRectsNoise(bool enable) {
  285. + RuntimeEnabledFeatures::SetFingerprintingClientRectsNoiseEnabled(enable);
  286. +}
  287. +
  288. +void WebRuntimeFeatures::EnableFingerprintingCanvasMeasureTextNoise(bool enable) {
  289. + RuntimeEnabledFeatures::SetFingerprintingCanvasMeasureTextNoiseEnabled(enable);
  290. +}
  291. +
  292. } // namespace blink
  293. --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
  294. +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
  295. @@ -747,6 +747,12 @@
  296. name: "FileSystem",
  297. status: "stable",
  298. },
  299. + {
  300. + name: "FingerprintingClientRectsNoise",
  301. + },
  302. + {
  303. + name: "FingerprintingCanvasMeasureTextNoise",
  304. + },
  305. // Perform style recalc traversal in the flat tree order, including marking
  306. // flat-tree instead of shadow-including ancestors for child dirtiness.
  307. {