Canvas Fingerprint Blocker

Block HTML canvas element from being used for fingerprinting purposes

  1. // ==UserScript==
  2. // @name Canvas Fingerprint Blocker
  3. // @namespace https://github.com/joue-quroi/canvas-fingerprint-blocker
  4. // @version 0.1
  5. // @description Block HTML canvas element from being used for fingerprinting purposes
  6. // @author Joue Quroi
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. if (document instanceof XMLDocument) {
  15. return;
  16. }
  17.  
  18. // https://add0n.com/canvas-fingerprint-blocker.html
  19. // https://github.com/joue-quroi/canvas-fingerprint-blocker
  20. // https://mybrowseraddon.com/canvas-defender.html
  21. // Modified by Ganlv
  22.  
  23. const toBlob = HTMLCanvasElement.prototype.toBlob;
  24. const toDataURL = HTMLCanvasElement.prototype.toDataURL;
  25.  
  26. HTMLCanvasElement.prototype.htGfd = function() {
  27. const {width, height} = this;
  28. const context = this.getContext('2d');
  29. const shift = {
  30. 'r': Math.floor(Math.random() * 10) - 5,
  31. 'g': Math.floor(Math.random() * 10) - 5,
  32. 'b': Math.floor(Math.random() * 10) - 5
  33. };
  34. const matt = context.getImageData(0, 0, width, height);
  35. for (let i = 0; i < height; i += 3) {
  36. for (let j = 0; j < width; j += 3) {
  37. const n = ((i * (width * 4)) + (j * 4));
  38. matt.data[n + 0] = matt.data[n + 0] + shift.r;
  39. matt.data[n + 1] = matt.data[n + 1] + shift.g;
  40. matt.data[n + 2] = matt.data[n + 2] + shift.b;
  41. }
  42. }
  43. context.putImageData(matt, 0, 0);
  44. this.htGfd = () => {
  45. window.top.postMessage('htGfd-called', '*');
  46. };
  47. window.top.postMessage('htGfd-called', '*');
  48. };
  49.  
  50. Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
  51. value: function() {
  52. if (document.documentElement.dataset.htgfd !== 'false') {
  53. this.htGfd();
  54. }
  55. return toBlob.apply(this, arguments);
  56. }
  57. });
  58. Object.defineProperty(HTMLCanvasElement.prototype, 'toDataURL', {
  59. value: function() {
  60. if (document.documentElement.dataset.htgfd !== 'false') {
  61. this.htGfd();
  62. }
  63. return toDataURL.apply(this, arguments);
  64. }
  65. });
  66. document.documentElement.dataset.htGfd = true;
  67. })();