Skip to content

Latest commit

 

History

History
338 lines (272 loc) · 9.7 KB

File metadata and controls

338 lines (272 loc) · 9.7 KB

Why Chromax Uses Native Fingerprint Protection

This document explains why Chromax's native Chromium fingerprint protection is superior to browser extensions and JavaScript injection methods.

🔍 Comparison of Approaches

1. Browser Extensions (e.g., Canvas Defender)

How it works:

  • Injects JavaScript into pages
  • Overrides browser APIs using Object.defineProperty()
  • Runs in content script context

Problems:

// Extensions leave traces
navigator.webdriver === true  // ❌ Detectable
window.chrome.runtime.id      // ❌ Extension ID exposed

// API overrides are detectable
const canvas = document.createElement('canvas');
const descriptor = Object.getOwnPropertyDescriptor(
  HTMLCanvasElement.prototype, 'toDataURL'
);
descriptor.get.toString()  // ❌ Shows it's been modified

Detection methods:

  • Check for navigator.webdriver
  • Check for extension IDs in window.chrome.runtime
  • Inspect property descriptors for modifications
  • Check function .toString() for native code
  • Look for timing anomalies in API calls

2. JavaScript Injection (e.g., Puppeteer Extra)

How it works:

  • Injects JavaScript before page load
  • Overrides APIs using Object.defineProperty()
  • Runs via Page.addScriptToEvaluateOnNewDocument()

Problems:

// Automation detection
navigator.webdriver === true  // ❌ Still present

// Function modifications detectable
HTMLCanvasElement.prototype.toDataURL.toString()
// Returns: "function toDataURL() { [injected code] }"
// Instead of: "function toDataURL() { [native code] }"

// Timing anomalies
const start = performance.now();
canvas.toDataURL();
const end = performance.now();
// ❌ Injected code is slower than native

Detection methods:

  • Check navigator.webdriver
  • Inspect function .toString() for "[native code]"
  • Measure API call timing
  • Check for iframe context mismatches
  • Look for property descriptor inconsistencies

3. Native Chromium Patches (Chromax) ✅

How it works:

  • Modifies Chromium C++ source code
  • Overrides APIs at the browser engine level
  • Controlled via command-line flags

Advantages:

// No automation detection
navigator.webdriver === undefined  // ✅ Not present

// Functions appear native
HTMLCanvasElement.prototype.toDataURL.toString()
// Returns: "function toDataURL() { [native code] }"  // ✅ Perfect

// No timing anomalies
const start = performance.now();
canvas.toDataURL();
const end = performance.now();
// ✅ Native performance, no overhead

// No extension artifacts
window.chrome.runtime === undefined  // ✅ Clean

Undetectable:

  • No navigator.webdriver
  • No extension IDs
  • Functions show "[native code]"
  • Native performance
  • No property descriptor modifications
  • No iframe context issues

📊 Feature Comparison

Feature Extensions JS Injection Native (Chromax)
Canvas Protection ⚠️ Detectable ⚠️ Detectable ✅ Undetectable
WebGL Protection ⚠️ Detectable ⚠️ Detectable ✅ Undetectable
Screen Override ❌ Limited ⚠️ Detectable ✅ Perfect
User-Agent ✅ Works ✅ Works ✅ Perfect
navigator.webdriver ❌ Present ❌ Present ✅ Removed
Function .toString() ❌ Modified ❌ Modified ✅ Native
Performance ⚠️ Slower ⚠️ Slower ✅ Native Speed
Extension Artifacts ❌ Present ✅ None ✅ None
Iframe Consistency ⚠️ Issues ⚠️ Issues ✅ Perfect
Worker Support ❌ Limited ❌ Limited ✅ Full
Automation Tools ✅ Works ✅ Works ✅ Works

🎯 Real-World Detection Examples

Example 1: Function toString() Check

Extensions/JS Injection:

const original = HTMLCanvasElement.prototype.toDataURL;
console.log(original.toString());
// Output: "function toDataURL() { /* injected code */ }"
// 🚨 DETECTED: Not native code!

Native Chromium (Chromax):

const original = HTMLCanvasElement.prototype.toDataURL;
console.log(original.toString());
// Output: "function toDataURL() { [native code] }"
// ✅ UNDETECTED: Appears as native code!

Example 2: Property Descriptor Check

Extensions/JS Injection:

const descriptor = Object.getOwnPropertyDescriptor(
  HTMLCanvasElement.prototype, 'toDataURL'
);
console.log(descriptor.value === descriptor.value);
// 🚨 DETECTED: Property has been redefined!

Native Chromium (Chromax):

const descriptor = Object.getOwnPropertyDescriptor(
  HTMLCanvasElement.prototype, 'toDataURL'
);
console.log(descriptor.value === descriptor.value);
// ✅ UNDETECTED: Original native property!

Example 3: Iframe Context Check

Extensions/JS Injection:

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeCanvas = iframe.contentWindow.HTMLCanvasElement.prototype.toDataURL;
const mainCanvas = HTMLCanvasElement.prototype.toDataURL;
console.log(iframeCanvas === mainCanvas);
// 🚨 DETECTED: Different functions in different contexts!

Native Chromium (Chromax):

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeCanvas = iframe.contentWindow.HTMLCanvasElement.prototype.toDataURL;
const mainCanvas = HTMLCanvasElement.prototype.toDataURL;
console.log(iframeCanvas === mainCanvas);
// ✅ UNDETECTED: Same native function everywhere!

Example 4: Web Worker Check

Extensions/JS Injection:

// In Web Worker
self.postMessage(HTMLCanvasElement.prototype.toDataURL.toString());
// 🚨 DETECTED: Worker context not protected!

Native Chromium (Chromax):

// In Web Worker
self.postMessage(HTMLCanvasElement.prototype.toDataURL.toString());
// ✅ UNDETECTED: Native code in all contexts!

🔬 Anti-Detection Test Suite

Here's a comprehensive test that websites use to detect fingerprint protection:

// Test 1: navigator.webdriver
if (navigator.webdriver) {
  console.log("🚨 DETECTED: Automation tool");
}

// Test 2: Function toString()
if (!HTMLCanvasElement.prototype.toDataURL.toString().includes('[native code]')) {
  console.log("🚨 DETECTED: Canvas API modified");
}

// Test 3: Property descriptor
const descriptor = Object.getOwnPropertyDescriptor(
  HTMLCanvasElement.prototype, 'toDataURL'
);
if (descriptor.writable !== true || descriptor.configurable !== true) {
  console.log("🚨 DETECTED: Property descriptor modified");
}

// Test 4: Iframe consistency
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
if (iframe.contentWindow.HTMLCanvasElement.prototype.toDataURL !==
    HTMLCanvasElement.prototype.toDataURL) {
  console.log("🚨 DETECTED: Iframe context mismatch");
}

// Test 5: Timing analysis
const start = performance.now();
for (let i = 0; i < 1000; i++) {
  document.createElement('canvas').toDataURL();
}
const end = performance.now();
if (end - start > 100) {  // Native should be < 10ms
  console.log("🚨 DETECTED: Timing anomaly");
}

// Test 6: Extension detection
if (window.chrome && window.chrome.runtime && window.chrome.runtime.id) {
  console.log("🚨 DETECTED: Extension present");
}

Results:

  • Browser Extensions: Fails tests 1, 2, 3, 4, 5, 6
  • JS Injection: Fails tests 1, 2, 3, 4, 5
  • Chromax (Native Chromium): ✅ Passes ALL tests

💪 Why Native is Superior

1. Undetectable

  • No JavaScript modifications
  • No extension artifacts
  • Functions show "[native code]"
  • No timing anomalies

2. Consistent

  • Works in all contexts (main, iframe, worker)
  • Same behavior across navigation
  • No race conditions

3. Fast

  • Native C++ performance
  • No JavaScript overhead
  • No runtime patching

4. Reliable

  • Can't be bypassed by websites
  • No context isolation issues
  • Works with strict CSP policies

5. Complete

  • Covers all APIs (Canvas, WebGL, Screen, etc.)
  • Works in Web Workers
  • Works in Service Workers
  • Works in all iframe contexts

🎓 Technical Deep Dive

How Extensions/JS Injection Work

// This is what extensions/injection do:
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function(...args) {
  // Add noise or modify output
  const result = originalToDataURL.apply(this, args);
  return modifyCanvasData(result);
};

Problems:

  1. Function is now a JavaScript function, not native
  2. .toString() shows JavaScript code
  3. Property descriptor is modified
  4. Slower performance (JavaScript overhead)
  5. Doesn't work in all contexts (workers, iframes)

How Native Chromium Works

// This is what native patches do (simplified):
// In chromium/src/third_party/blink/renderer/core/html/canvas/...

String HTMLCanvasElement::toDataURL(const String& type, ...) {
  String result = OriginalToDataURL(type, ...);
  
  // Check command-line flag
  if (RuntimeEnabledFeatures::FingerprintCanvasModeEnabled()) {
    String mode = GetFingerprintCanvasMode();
    if (mode == "noise") {
      result = AddCanvasNoise(result, GetFingerprintCanvasSeed());
    }
  }
  
  return result;
}

Advantages:

  1. Function remains native C++ code
  2. .toString() shows "[native code]"
  3. Property descriptor unchanged
  4. Native performance
  5. Works in ALL contexts automatically

🏆 Conclusion

Native Chromium fingerprint protection is the ONLY truly undetectable method.

  • ✅ No JavaScript modifications
  • ✅ No extension artifacts
  • ✅ Native performance
  • ✅ Works everywhere
  • ✅ Future-proof

This is why professional anti-detect browsers (Multilogin, GoLogin, etc.) all use custom Chromium builds rather than extensions.


Ready to use it? Check out the Quick Start Guide!