// ==UserScript==
// @name Universal Bypass
// @namespace https://github.com/x3ric
// @version 1.3
// @description Bypass common web restrictions: right-click, copy-paste, text selection, drag/drop, scrolling, video controls, console, debugger, and more.
// @author x3ric
// @license MIT
// @match *://*/*
// @run-at document-start
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_notification
// @grant GM_unregisterMenuCommand
// @grant unsafeWindow
// ==/UserScript==
(function() {
'use strict';
const settings = GM_getValue('universalBypassSettings', {
rightClick: true,
copyPaste: true,
textSelection: true,
consoleBypass: false,
debuggerBypass: false
});
const saveSettings = () => GM_setValue('universalBypassSettings', settings);
const applyBypasses = () => {
if (settings.rightClick) {
document.addEventListener('contextmenu', handleContextMenu, true);
unsafeWindow.oncontextmenu = null;
}
if (settings.copyPaste) {
['copy', 'paste', 'cut'].forEach(ev =>
document.addEventListener(ev, handleCopyPaste, true)
);
}
if (settings.textSelection) {
document.addEventListener('selectstart', handleTextSelection, true);
applyTextSelectionStyle();
}
if (settings.consoleBypass) {
applyConsoleBypass();
}
if (settings.debuggerBypass) {
applyDebuggerBypass();
}
// Override common protection methods
overrideProtectionMethods();
};
const handleContextMenu = (e) => {
e.stopImmediatePropagation();
unsafeWindow.oncontextmenu = null;
return true;
};
const handleCopyPaste = (e) => {
e.stopImmediatePropagation();
return true;
};
const handleTextSelection = (e) => {
e.stopImmediatePropagation();
return true;
};
const applyTextSelectionStyle = () => {
const style = document.createElement('style');
style.textContent = `
* {
user-select: text !important;
-webkit-user-select: text !important;
-moz-user-select: text !important;
-ms-user-select: text !important;
}
::selection {
background: #b3d4fc !important;
color: #000 !important;
}
`;
document.head.appendChild(style);
};
const applyConsoleBypass = () => {
const noop = () => {};
const consoleProxy = new Proxy(console, {
get: (target, prop) => {
if (['clear', 'debug', 'error', 'info', 'log', 'warn'].includes(prop)) {
return noop;
}
return target[prop];
}
});
Object.defineProperty(unsafeWindow, 'console', {
get: () => consoleProxy,
set: () => {},
configurable: false
});
};
const applyDebuggerBypass = () => {
const handler = {
get: (target, prop) => {
if (prop === 'toString') {
return () => 'function () { [native code] }';
}
return typeof target[prop] === 'function' ?
target[prop].bind(target) : target[prop];
}
};
unsafeWindow.Function = new Proxy(unsafeWindow.Function, handler);
unsafeWindow.eval = new Proxy(unsafeWindow.eval, {
apply: (target, thisArg, args) => {
args[0] = args[0].replace(/debugger/g, '');
return Reflect.apply(target, thisArg, args);
}
});
};
const overrideProtectionMethods = () => {
const overrides = {
preventDefault: Event.prototype.preventDefault,
stopPropagation: Event.prototype.stopPropagation,
stopImmediatePropagation: Event.prototype.stopImmediatePropagation
};
Object.keys(overrides).forEach(method => {
Event.prototype[method] = new Proxy(overrides[method], {
apply: (target, thisArg, args) => {
if (!['contextmenu', 'copy', 'paste', 'cut', 'selectstart'].includes(thisArg.type)) {
return Reflect.apply(target, thisArg, args);
}
}
});
});
};
const menuCommands = {};
const updateMenuCommand = (key) => {
if (menuCommands[key]) {
GM_unregisterMenuCommand(menuCommands[key]);
}
menuCommands[key] = GM_registerMenuCommand(
`${key.replace(/([A-Z])/g, ' $1').trim()} (${settings[key] ? 'ON' : 'OFF'})`,
() => toggleSetting(key)
);
};
const toggleSetting = key => {
settings[key] = !settings[key];
saveSettings();
applyBypasses();
updateMenuCommand(key);
GM_notification({
text: `${key.replace(/([A-Z])/g, ' $1').trim()} is now ${settings[key] ? 'ON' : 'OFF'}`,
title: 'Universal Bypass',
timeout: 3000
});
};
Object.keys(settings).forEach(updateMenuCommand);
// Initial application
applyBypasses();
// Reapply on possible DOM changes
const observer = new MutationObserver(applyBypasses);
observer.observe(document, { childList: true, subtree: true });
// Reapply on navigation events
['load', 'popstate', 'pushstate', 'replacestate'].forEach(event =>
window.addEventListener(event, applyBypasses, true)
);
})();