Universal Bypass

Bypass common web restrictions: right-click, copy-paste, text selection, console, debugger, and more.

As of 2025-01-10. See the latest version.

  1. // ==UserScript==
  2. // @name Universal Bypass
  3. // @namespace https://github.com/x3ric
  4. // @version 1.5
  5. // @description Bypass common web restrictions: right-click, copy-paste, text selection, console, debugger, and more.
  6. // @author x3ric
  7. // @license MIT
  8. // @match *://*/*
  9. // @run-at document-start
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @grant GM_registerMenuCommand
  13. // @grant GM_unregisterMenuCommand
  14. // @grant GM_notification
  15. // @grant unsafeWindow
  16. // @inject-into page
  17. // @compatible firefox Violentmonkey
  18. // @compatible firefox Tampermonkey
  19. // @compatible chrome Violentmonkey
  20. // @compatible chrome Tampermonkey
  21. // @compatible opera Violentmonkey
  22. // @compatible opera Tampermonkey
  23. // @compatible safari Stay
  24. // @compatible edge Violentmonkey
  25. // @compatible edge Tampermonkey
  26. // @compatible brave Violentmonkey
  27. // @compatible brave Tampermonkey
  28. // ==/UserScript==
  29.  
  30. (function() {
  31. 'use strict';
  32.  
  33. // Load settings or set defaults if not already saved
  34. const settings = GM_getValue('universalBypassSettings', {
  35. rightClick: true,
  36. copyPaste: true,
  37. textSelection: true,
  38. consoleBypass: false,
  39. debuggerBypass: false
  40. });
  41.  
  42. // Save settings to storage
  43. const saveSettings = () => {
  44. GM_setValue('universalBypassSettings', settings);
  45. };
  46.  
  47. // Function to remove all added listeners from problematic scripts
  48. const removeAllEventListeners = () => {
  49. var newElement = document.createElement('div');
  50. newElement.innerHTML = document.body.innerHTML;
  51. document.body.innerHTML = newElement.innerHTML;
  52. };
  53.  
  54. // Function to apply bypasses based on settings
  55. const applyBypasses = () => {
  56. if (settings.rightClick) {
  57. window.addEventListener('contextmenu', e => e.stopImmediatePropagation(), { once: true, capture: true });
  58. }
  59.  
  60. if (settings.copyPaste) {
  61. // Nullify any set event handlers that restrict copy/paste operations
  62. document.onkeydown = null;
  63. document.onselectstart = null;
  64. document.onmousedown = null;
  65. document.onclick = null;
  66. document.body.oncopy = document.body.oncut = document.body.onpaste = null;
  67.  
  68. ['copy', 'paste', 'cut'].forEach(ev => {
  69. document.addEventListener(ev, e => e.stopImmediatePropagation(), { capture: true });
  70. });
  71.  
  72. // Reset event listeners on body's HTML content replacement
  73. window.onload = removeAllEventListeners;
  74. document.addEventListener('DOMContentLoaded', removeAllEventListeners);
  75. document.addEventListener('touchstart', e => e.stopPropagation(), true);
  76. document.addEventListener('touchend', e => e.stopPropagation(), true);
  77. }
  78.  
  79. if (settings.textSelection) {
  80. // Override CSS to enable text selection
  81. document.querySelectorAll('*').forEach(el => {
  82. el.style.userSelect = 'text';
  83. el.style.cursor = 'auto';
  84. });
  85.  
  86. const style = document.createElement('style');
  87. style.textContent = '* { user-select: text !important; -webkit-user-select: text !important; }';
  88. document.head.appendChild(style);
  89. }
  90.  
  91. if (settings.consoleBypass) {
  92. ['log', 'warn', 'error', 'debug', 'info'].forEach(func => {
  93. console[func] = () => {};
  94. });
  95. }
  96.  
  97. if (settings.debuggerBypass) {
  98. unsafeWindow.eval = new Proxy(unsafeWindow.eval, {
  99. apply: (target, thisArg, args) => {
  100. args[0] = args[0].replace(/debugger/g, '');
  101. return Reflect.apply(target, thisArg, args);
  102. }
  103. });
  104. }
  105. };
  106.  
  107. // Toggle individual settings
  108. const toggleSetting = key => {
  109. settings[key] = !settings[key];
  110. saveSettings();
  111. applyBypasses();
  112. GM_notification({
  113. text: `${key} is now ${settings[key] ? 'enabled' : 'disabled'}.`,
  114. title: 'Setting Toggled',
  115. timeout: 2500
  116. });
  117. };
  118.  
  119. // Register menu commands for toggling settings
  120. Object.keys(settings).forEach(key => {
  121. GM_registerMenuCommand(`${key} ${settings[key] ? 'ON' : 'OFF'}`, () => toggleSetting(key));
  122. });
  123.  
  124. applyBypasses();
  125.  
  126. // Observe DOM changes to reapply bypasses if necessary
  127. const observer = new MutationObserver(() => applyBypasses());
  128. observer.observe(document.documentElement, { childList: true, subtree: true });
  129.  
  130. // Reapply bypasses on page navigation events to ensure consistency
  131. ['load', 'popstate', 'pushstate', 'replacestate'].forEach(event =>
  132. window.addEventListener(event, applyBypasses, true)
  133. );
  134. })();