Block Touchscreen Fingerprinting

Force navigator.maxTouchPoints=0 on Firefox/LibreWolf.

// ==UserScript==
// @name         Block Touchscreen Fingerprinting
// @namespace    https://example.com/
// @version      1.3
// @description  Force navigator.maxTouchPoints=0 on Firefox/LibreWolf.
// @match        *://*/*
// @run-at       document-start
// @all-frames   true
// @grant        none
// @inject-into  page
// ==/UserScript==

(() => {
  'use strict';
  const inject = (fn) => {
    try {
      const s = document.createElement('script');
      s.textContent = `(${fn})();`;
      (document.documentElement || document.head || document.body).appendChild(s);
      s.remove();
    } catch {
      fn();
    }
  };
  const main = () => {
    try {
      const proto = (typeof Navigator === 'function' && Navigator.prototype) || Object.getPrototypeOf(navigator);
      if (!proto) return;

      const redefine = (target, prop, value) => {
        const d = Object.getOwnPropertyDescriptor(target, prop);
        if (!d) return false;
        if (typeof d.get === 'function') {
          const nativeSrc = Function.prototype.toString.call(d.get);
          const nativeName = d.get.name;
          const getter = function() { return value; };
          try { Object.defineProperty(getter, 'toString', { value: () => nativeSrc }); } catch {}
          try { if (nativeName) Object.defineProperty(getter, 'name', { value: nativeName }); } catch {}
          Object.defineProperty(target, prop, {
            get: getter,
            set: d.set,
            enumerable: d.enumerable,
            configurable: d.configurable
          });
          return true;
        } else if ('value' in d) {
          try {
            Object.defineProperty(target, prop, {
              value,
              writable: d.writable,
              enumerable: d.enumerable,
              configurable: d.configurable
            });
            return true;
          } catch { return false; }
        }
        return false;
      };

      let cur = 0;
      try { cur = navigator.maxTouchPoints; } catch {}
      if (cur !== 0) {
        if (!redefine(proto, 'maxTouchPoints', 0) &&
            !redefine(navigator, 'maxTouchPoints', 0)) {
          try { Object.defineProperty(navigator, 'maxTouchPoints', { value: 0, configurable: true }); } catch {}
        }
      }

      if (('msMaxTouchPoints' in proto) || ('msMaxTouchPoints' in navigator)) {
        if (!redefine(proto, 'msMaxTouchPoints', 0)) {
          redefine(navigator, 'msMaxTouchPoints', 0);
        }
      }
    } catch {}
  };
  inject(main);
})();