Bypass DevTools Detection

Prevent websites from detecting DevTools (Inspect Element) is open

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Bypass DevTools Detection
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Prevent websites from detecting DevTools (Inspect Element) is open
// @author       Serial Desegnation J
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // --- Override debugger to noop ---
    window.debugger = function() {};

    // Spoof Function.prototype.constructor to strip debugger statements from strings
    const originalConstructor = Function.prototype.constructor;
    Function.prototype.constructor = new Proxy(originalConstructor, {
        apply(target, thisArg, args) {
            if (args[0] && typeof args[0] === 'string' && args[0].includes('debugger')) {
                args[0] = args[0].replace(/debugger/g, '');
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Spoof Function.prototype.toString to hide overrides (especially debugger function)
    const originalToString = Function.prototype.toString;
    Function.prototype.toString = new Proxy(originalToString, {
        apply(target, thisArg, args) {
            if (thisArg === window.debugger) {
                return 'function debugger() { [native code] }';
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Override eval to strip debugger statements from any eval'd code
    const originalEval = window.eval;
    window.eval = function(code) {
        if (typeof code === 'string') {
            code = code.replace(/debugger;?/g, '');
        }
        return originalEval(code);
    };

    // Override console methods to disable traps and weird behaviors
    ['log', 'debug', 'error', 'info', 'warn'].forEach(method => {
        const originalMethod = console[method];
        console[method] = function(...args) {
            // Skip logging if args include certain trap images or weird data (optional)
            for (const arg of args) {
                if (arg instanceof Image) return;
            }
            return originalMethod.apply(console, args);
        };
    });

    // Block console.clear to prevent wiping logs
    console.clear = function () {
        console.log('[Tampermonkey] Blocked console.clear()');
    };

    // Spoof window.outerWidth and outerHeight to match inner dimensions (for devtools detection)
    function spoofWindowSize() {
        Object.defineProperty(window, 'outerWidth', {
            get: () => window.innerWidth,
            configurable: true
        });
        Object.defineProperty(window, 'outerHeight', {
            get: () => window.innerHeight,
            configurable: true
        });
    }
    spoofWindowSize();
    // Repeat periodically to counter site attempts to redefine
    setInterval(spoofWindowSize, 1000);

    // Override requestAnimationFrame to fudge timestamps (blocks timing detection)
    const originalRAF = window.requestAnimationFrame;
    window.requestAnimationFrame = function(callback) {
        return originalRAF(function(time) {
            callback(time + 1000);
        });
    };

    // Prevent key combos that open DevTools or View Source
    document.addEventListener('keydown', function(e) {
        if (
            e.key === 'F12' ||
            (e.ctrlKey && e.shiftKey && ['I', 'J', 'C'].includes(e.key.toUpperCase())) ||
            (e.ctrlKey && e.key.toUpperCase() === 'U')
        ) {
            e.stopImmediatePropagation();
            e.preventDefault();
        }
    }, true);

    // Prevent detection via image get traps (used in object inspection)
    const imageProto = Object.getPrototypeOf(new Image());
    if (imageProto) {
        Object.defineProperty(imageProto, 'id', {
            get: function() {
                return null;
            },
            configurable: true
        });
    }

    // Spoof performance navigation type to hide reload detection
    try {
        if (performance.getEntriesByType("navigation")[0].type === "reload") {
            Object.defineProperty(performance, 'getEntriesByType', {
                value: () => [{ type: "navigate" }],
                configurable: true
            });
        }
    } catch (e) {}

    // Spoof navigator.plugins and navigator.languages to look real
    Object.defineProperty(navigator, 'plugins', {
        get: () => [1, 2, 3],
        configurable: true
    });
    Object.defineProperty(navigator, 'languages', {
        get: () => ['en-US', 'en'],
        configurable: true
    });

    // Spoof HTMLElement.prototype.toString to prevent element inspection detection
    const originalGetOwnPropDesc = Object.getOwnPropertyDescriptor;
    Object.getOwnPropertyDescriptor = new Proxy(originalGetOwnPropDesc, {
        apply(target, thisArg, args) {
            if (args[0] === HTMLElement.prototype && args[1] === 'toString') {
                return {
                    configurable: true,
                    enumerable: false,
                    value: () => '[object HTMLElement]'
                };
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Debugging confirmation message
    console.log('[Tampermonkey] DevTools detection blocked (enhanced).');

})();