Anti-Fingerprinting Shield Plus

Spoofs browser fingerprint data: canvas, WebGL, audio, language, timezone, userAgent, screen size, memory, and more. Spoofed values persist across tabs and expire after 30 minutes to simulate session behavior realistically. Top-frame only execution for stealth and compatibility.

目前為 2025-05-03 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Anti-Fingerprinting Shield Plus
// @namespace    https://365devnet.eu/userscripts
// @version      4.5
// @description  Spoofs browser fingerprint data: canvas, WebGL, audio, language, timezone, userAgent, screen size, memory, and more. Spoofed values persist across tabs and expire after 30 minutes to simulate session behavior realistically. Top-frame only execution for stealth and compatibility.
// @author       Richard B
// @match        *://*/*
// @run-at       document-start
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';

  if (window.top !== window.self) return;

  const DEBUG_MODE = true;
  const SESSION_TIMEOUT_MINUTES = 30;
  const sessionExpiryKey = '__afs_last_seen';
  const now = Date.now();

  const isExpired = () => {
    const lastSeen = parseInt(localStorage.getItem(sessionExpiryKey), 10);
    return isNaN(lastSeen) || now - lastSeen > SESSION_TIMEOUT_MINUTES * 60 * 1000;
  };

  if (isExpired()) {
    clearStoredSpoofedValues();
    if (DEBUG_MODE) console.log(`[AFS+] New session started (values expired after ${SESSION_TIMEOUT_MINUTES} minutes)`);
  }
  localStorage.setItem(sessionExpiryKey, now.toString());

  const sessionId = getOrCreatePersistent('__afs_session_id', () =>
    Math.random().toString(36).substring(2, 10)
  );

  if (DEBUG_MODE) console.log(`[AFS+] Anti-Fingerprinting Shield v4.5 started. Session ID: ${sessionId}`);

  const platforms = ['Win32', 'Linux x86_64', 'MacIntel', 'FreeBSD'];
  const languages = ['en-US', 'nl-NL', 'fr-FR', 'de-DE', 'sv-SE'];
  const timezones = ['UTC', 'Europe/Amsterdam', 'America/New_York', 'Asia/Tokyo'];
  const userAgents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
  ];
  const cores = [2, 4, 6, 8];
  const memorySizes = [2, 4, 8];
  const screenWidths = [1920, 1680, 1366];
  const screenHeights = [1080, 1050, 768];

  const spoofed = {
    platform: getOrCreatePersistent('platform', () => pick(platforms)),
    language: getOrCreatePersistent('language', () => pick(languages)),
    languages: () => [spoofed.language, 'en'],
    timezone: getOrCreatePersistent('timezone', () => pick(timezones)),
    userAgent: getOrCreatePersistent('userAgent', () => pick(userAgents)),
    cores: parseInt(getOrCreatePersistent('cores', () => pick(cores))),
    memory: parseInt(getOrCreatePersistent('memory', () => pick(memorySizes))),
    screenWidth: parseInt(getOrCreatePersistent('screenWidth', () => pick(screenWidths))),
    screenHeight: parseInt(getOrCreatePersistent('screenHeight', () => pick(screenHeights))),
    vendor: 'SpoofedVendor',
    doNotTrack: Math.random() > 0.5 ? '1' : '0'
  };

  function pick(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
  }

  function getOrCreatePersistent(key, generator) {
    const fullKey = '__afs_' + key;
    let value = localStorage.getItem(fullKey);
    if (!value) {
      value = generator();
      localStorage.setItem(fullKey, value);
    }
    return value;
  }

  function clearStoredSpoofedValues() {
    Object.keys(localStorage)
      .filter(key => key.startsWith('__afs_'))
      .forEach(key => localStorage.removeItem(key));
  }

  function spoof(obj, prop, valueFn) {
    try {
      Object.defineProperty(obj, prop, {
        get: valueFn,
        configurable: true
      });
    } catch (e) {}
  }

  spoof(navigator, 'language', () => spoofed.language);
  spoof(navigator, 'languages', () => spoofed.languages());
  spoof(navigator, 'platform', () => spoofed.platform);
  spoof(navigator, 'userAgent', () => spoofed.userAgent);
  spoof(navigator, 'hardwareConcurrency', () => spoofed.cores);
  spoof(navigator, 'deviceMemory', () => spoofed.memory);
  spoof(navigator, 'vendor', () => spoofed.vendor);
  spoof(navigator, 'doNotTrack', () => spoofed.doNotTrack);
  spoof(navigator, 'maxTouchPoints', () => 1);
  spoof(navigator, 'plugins', () => []);
  spoof(navigator, 'mimeTypes', () => ({ length: 0 }));
  spoof(navigator, 'mediaDevices', () => ({ enumerateDevices: () => Promise.resolve([]) }));
  spoof(navigator, 'webdriver', () => false);
  spoof(navigator, 'connection', () => ({ downlink: 10, effectiveType: '4g', rtt: 50, saveData: false }));
  spoof(navigator, 'mediaCapabilities', () => undefined);
  spoof(navigator, 'mediaSession', () => undefined);

  if (navigator.permissions && navigator.permissions.query) {
    const originalQuery = navigator.permissions.query;
    navigator.permissions.query = function (params) {
      if (params.name === 'notifications') {
        return Promise.resolve({ state: 'denied' });
      }
      return originalQuery.call(this, params);
    };
  }

  spoof(window.screen, 'width', () => spoofed.screenWidth);
  spoof(window.screen, 'height', () => spoofed.screenHeight);
  spoof(window, 'innerWidth', () => spoofed.screenWidth);
  spoof(window, 'innerHeight', () => spoofed.screenHeight - 40);

  try {
    const original = Intl.DateTimeFormat.prototype.resolvedOptions;
    Intl.DateTimeFormat.prototype.resolvedOptions = function () {
      const options = original.call(this);
      options.timeZone = spoofed.timezone;
      return options;
    };
  } catch (e) {}

  spoof(Date.prototype, 'getTimezoneOffset', () => {
    const offsetMap = { 'UTC': 0, 'Europe/Amsterdam': -120, 'America/New_York': 300, 'Asia/Tokyo': -540 };
    return offsetMap[spoofed.timezone] || 0;
  });

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  if (AudioContext) {
    spoof(AudioContext.prototype, 'sampleRate', () => 44100);
    if (AnalyserNode.prototype.getFloatFrequencyData) {
      const original = AnalyserNode.prototype.getFloatFrequencyData;
      AnalyserNode.prototype.getFloatFrequencyData = function (arr) {
        original.call(this, arr);
        for (let i = 0; i < arr.length; i++) {
          arr[i] += Math.random() * 0.1;
        }
      };
    }
  }

  const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
  CanvasRenderingContext2D.prototype.getImageData = function (x, y, w, h) {
    const data = originalGetImageData.call(this, x, y, w, h);
    for (let i = 0; i < data.data.length; i += 4) {
      data.data[i] += Math.floor(Math.random() * 3);
      data.data[i + 1] += Math.floor(Math.random() * 3);
      data.data[i + 2] += Math.floor(Math.random() * 3);
    }
    return data;
  };

  const originalGL = WebGLRenderingContext.prototype.getParameter;
  WebGLRenderingContext.prototype.getParameter = function (param) {
    const spoofMap = { 37445: 'FakeVendor Inc.', 37446: 'Virtual GPU Renderer', 3379: 4096, 35661: 8 };
    return spoofMap[param] || originalGL.call(this, param);
  };

  WebGLRenderingContext.prototype.getShaderPrecisionFormat = function () {
    return { rangeMin: 127, rangeMax: 127, precision: 23 };
  };

  performance.now = () => Math.floor(performance.timeOrigin + Math.random() * 100);

  navigator.storage.estimate = () => Promise.resolve({ usage: 5242880, quota: 1073741824 });

  window.RTCPeerConnection = undefined;
  window.webkitRTCPeerConnection = undefined;
  window.Bluetooth = undefined;
  delete navigator.getBattery;
  delete navigator.bluetooth;

  window.DeviceMotionEvent = undefined;
  window.DeviceOrientationEvent = undefined;

  window.addEventListener('devicemotion', e => e.stopImmediatePropagation(), true);
  window.addEventListener('deviceorientation', e => e.stopImmediatePropagation(), true);

  window.addEventListener('beforeunload', e => {
    e.stopImmediatePropagation();
    e.preventDefault();
    return undefined;
  }, true);

  if (DEBUG_MODE) {
    console.group(`[AFS+] Spoofed Fingerprint for Session: ${sessionId}`);
    console.log('User Agent     :', spoofed.userAgent);
    console.log('Platform       :', spoofed.platform);
    console.log('Language       :', spoofed.language);
    console.log('Languages      :', spoofed.languages().join(', '));
    console.log('Timezone       :', spoofed.timezone);
    console.log('CPU Cores      :', spoofed.cores);
    console.log('Device Memory  :', spoofed.memory);
    console.log('Screen Width   :', spoofed.screenWidth);
    console.log('Screen Height  :', spoofed.screenHeight);
    console.log('Vendor         :', spoofed.vendor);
    console.log('DNT            :', spoofed.doNotTrack);
    console.groupEnd();
  }
})();