-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
Description
Description
it allows have static noise
Who's implementing?
- I'm willing to implement this feature myself
The problem
for example, when i reloaded pixelscan.net i have different canvas hash. solution - use static seed based on tomething static of profile
Possible solutions
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -40,6 +40,11 @@
#include "base/i18n/time_formatting.h"
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
+#include "base/rand_util.h"
+#include "base/logging.h"
+#include "base/command_line.h"
+#include "base/hash/hash.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -1089,6 +1090,16 @@ Document::Document(const DocumentInit& i
TRACE_EVENT_WITH_FLOW0("blink", "Document::Document", TRACE_ID_LOCAL(this),
TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(agent_);
+ if (RuntimeEnabledFeatures::FingerprintingClientRectsNoiseEnabled()) {
+ // Precompute -0.0003% to 0.0003% noise factor for get*ClientRect*() fingerprinting
+ const auto seed_base_ = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative("user-data-dir");
+ uint32_t seed = seed_base_.empty() ? 0u : base::PersistentHash(base::WideToUTF8(seed_base_));
+ // извлекаем две 20-битные мантиссы из seed
+ double noise_x = 1.0 + (((seed & 0xFFFFF) / static_cast<double>(0x100000)) - 0.5) * 0.000003;
+ double noise_y = 1.0 + ((((seed >> 20) & 0xFFFFF) / static_cast<double>(0x100000)) - 0.5) * 0.000003;
+ noise_factor_x_ = noise_x;
+ noise_factor_y_ = noise_y;
+ }
if (base::FeatureList::IsEnabled(features::kDelayAsyncScriptExecution) &&
features::kDelayAsyncScriptExecutionDelayByDefaultParam.Get()) {
script_runner_delayer_->Activate();--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.cc
@@ -4,6 +4,11 @@
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+#include "base/rand_util.h"
+#include "base/logging.h"
+#include "base/command_line.h"
+#include "base/hash/hash.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/numerics/checked_math.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
@@ -11,11 +13,13 @@
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/src/core/SkColorData.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "v8/include/v8.h"
@@ -114,4 +118,163 @@ void StaticBitmapImage::DrawHelper(cc::P
ToSkiaRectConstraint(draw_options.clamping_mode));
}
+// set the component to maximum-delta if it is >= maximum, or add to existing color component (color + delta)
+#define shuffleComponent(color, max, delta) ( (color) >= (max) ? ((max)-(delta)) : ((color)+(delta)) )
+
+#define writable_addr(T, p, stride, x, y) (T*)((const char *)p + y * stride + x * sizeof(T))
+
+void StaticBitmapImage::ShuffleSubchannelColorData(const void *addr, const SkImageInfo& info, int srcX, int srcY) {
+ auto w = info.width() - srcX, h = info.height() - srcY;
+
+ // skip tiny images; info.width()/height() can also be 0
+ if ((w < 8) || (h < 8)) {
+ return;
+ }
+
+ const auto add_flgaw = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative("user-data-dir");
+ uint32_t seed = add_flgaw.empty() ? 0u : base::PersistentHash(base::WideToUTF8(add_flgaw));
+
+ // Generate two fixed factors from seed (0..1 range)
+ double shuffleX = (seed & 0xFFFFF) / static_cast<double>(0x100000);
+ double shuffleY = ((seed >> 20) & 0xFFFFF) / static_cast<double>(0x100000);
+
+ // cap maximum pixels to change
+ auto pixels = (w + h) / 128;
+ if (pixels > 10) {
+ pixels = 10;
+ } else if (pixels < 2) {
+ pixels = 2;
+ }
+
+ auto colorType = info.colorType();
+ auto fRowBytes = info.minRowBytes(); // stride
+
+ DLOG(INFO) << "BRM: ShuffleSubchannelColorData() w=" << w << " h=" << h << " colorType=" << colorType << " fRowBytes=" << fRowBytes;
+
+ // calculate random coordinates using bisection
+ auto currentW = w, currentH = h;
+ for(;pixels >= 0; pixels--) {
+ int x = currentW * shuffleX, y = currentH * shuffleY;
+
+ // Deterministic per-pixel randomisation amounts
+ uint32_t r = seed;
+ r ^= (pixels * 0x9e3779b9);
+ r ^= (x * 0x8329c8eb);
+ r ^= (y * 0x2a9d8f7b);
+ r = (r ^ (r >> 16)) * 0x85ebca6b;
+ r = (r ^ (r >> 13)) * 0xc2b2ae35;
+ r ^= (r >> 16);
+
+ uint8_t shuffleR = (r >> 24) % 5;
+ uint8_t shuffleG = (shuffleR + x) % 4;
+ uint8_t shuffleB = (shuffleG + y) % 4;
+
+ // manipulate pixel data to slightly change the R, G, B components
+ switch (colorType) {
+ case kAlpha_8_SkColorType:
+ {
+ auto *pixel = writable_addr(uint8_t, addr, fRowBytes, x, y);
+ auto r = SkColorGetR(*pixel), g = SkColorGetG(*pixel), b = SkColorGetB(*pixel), a = SkColorGetA(*pixel);
+
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
+ // alpha is left unchanged
+
+ *pixel = SkColorSetARGB(a, r, g, b);
+ }
+ break;
+ case kGray_8_SkColorType:
+ {
+ auto *pixel = writable_addr(uint8_t, addr, fRowBytes, x, y);
+ *pixel = shuffleComponent(*pixel, UINT8_MAX-1, shuffleB);
+ }
+ break;
+ case kRGB_565_SkColorType:
+ {
+ auto *pixel = writable_addr(uint16_t, addr, fRowBytes, x, y);
+ unsigned r = SkPacked16ToR32(*pixel);
+ unsigned g = SkPacked16ToG32(*pixel);
+ unsigned b = SkPacked16ToB32(*pixel);
+
+ r = shuffleComponent(r, 31, shuffleR);
+ g = shuffleComponent(g, 63, shuffleG);
+ b = shuffleComponent(b, 31, shuffleB);
+
+ unsigned r16 = (r & SK_R16_MASK) << SK_R16_SHIFT;
+ unsigned g16 = (g & SK_G16_MASK) << SK_G16_SHIFT;
+ unsigned b16 = (b & SK_B16_MASK) << SK_B16_SHIFT;
+
+ *pixel = r16 | g16 | b16;
+ }
+ break;
+ case kARGB_4444_SkColorType:
+ {
+ auto *pixel = writable_addr(uint16_t, addr, fRowBytes, x, y);
+ auto a = SkGetPackedA4444(*pixel), r = SkGetPackedR4444(*pixel), g = SkGetPackedG4444(*pixel), b = SkGetPackedB4444(*pixel);
+
+ r = shuffleComponent(r, 15, shuffleR);
+ g = shuffleComponent(g, 15, shuffleG);
+ b = shuffleComponent(b, 15, shuffleB);
+ // alpha is left unchanged
+
+ unsigned a4 = (a & 0xF) << SK_A4444_SHIFT;
+ unsigned r4 = (r & 0xF) << SK_R4444_SHIFT;
+ unsigned g4 = (g & 0xF) << SK_G4444_SHIFT;
+ unsigned b4 = (b & 0xF) << SK_B4444_SHIFT;
+
+ *pixel = r4 | b4 | g4 | a4;
+ }
+ break;
+ case kRGBA_8888_SkColorType:
+ {
+ auto *pixel = writable_addr(uint32_t, addr, fRowBytes, x, y);
+ auto a = SkGetPackedA32(*pixel), r = SkGetPackedR32(*pixel), g = SkGetPackedG32(*pixel), b = SkGetPackedB32(*pixel);
+
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
+ // alpha is left unchanged
+
+ *pixel = (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
+ (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
+ }
+ break;
+ case kBGRA_8888_SkColorType:
+ {
+ auto *pixel = writable_addr(uint32_t, addr, fRowBytes, x, y);
+ auto a = SkGetPackedA32(*pixel), b = SkGetPackedR32(*pixel), g = SkGetPackedG32(*pixel), r = SkGetPackedB32(*pixel);
+
+ r = shuffleComponent(r, UINT8_MAX-1, shuffleR);
+ g = shuffleComponent(g, UINT8_MAX-1, shuffleG);
+ b = shuffleComponent(b, UINT8_MAX-1, shuffleB);
+ // alpha is left unchanged
+
+ *pixel = (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) |
+ (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
+ }
+ break;
+ default:
+ // the remaining formats are not expected to be used in Chromium
+ LOG(WARNING) << "BRM: ShuffleSubchannelColorData(): Ignoring pixel format";
+ return;
+ }
+
+ // keep bisecting or reset current width/height as needed
+ if (x == 0) {
+ currentW = w;
+ } else {
+ currentW = x;
+ }
+ if (y == 0) {
+ currentH = h;
+ } else {
+ currentH = y;
+ }
+ }
+}
+
+#undef writable_addr
+#undef shuffleComponent
+
} // namespace blinkfingerprinting-flags-client-rects-and-measuretext.patch
flag-fingerprinting-canvas-image-data-noise.patch
Alternatives
No response
Additional context
No response
Reactions are currently unavailable