Stop Nefarious Redirects

Block unauthorized redirects and prevent history manipulation

目前為 2024-05-28 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Stop Nefarious Redirects
// @namespace    http://tampermonkey.net/
// @version      4.1
// @description  Block unauthorized redirects and prevent history manipulation
// @match        http://*/*
// @match        https://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @license      MIT
// @run-at       document-start
// ==/UserScript==

const manualBlacklist = new Set([
    'getrunkhomuto.info'
]);

const allowedPopups = [
    '500px.com', 'accuweather.com', 'adobe.com', 'adulttime.com', 'alibaba.com', 'amazon.com', 'amazonaws.com',
    /* ... */
    'zeplin.iozillow.com', 'zoom.us'
];

(function() {
    'use strict';

    console.log('Script initialization started.');

    /**
     * Get the current automated blacklist
     * @returns {Set} The automated blacklist
     */
    function getAutomatedBlacklist() {
        return new Set(GM_getValue('blacklist', []));
    }

    /**
     * Add a URL to the automated blacklist
     * @param {string} url - The URL to add to the blacklist
     */
    function addToAutomatedBlacklist(url) {
        const encodedUrl = encodeURIComponent(url);
        const blacklist = getAutomatedBlacklist();
        if (!blacklist.has(encodedUrl)) {
            blacklist.add(encodedUrl);
            GM_setValue('blacklist', Array.from(blacklist));
            console.log('Added to automated blacklist:', url);
        }
    }

    /**
     * Check if navigation to a URL is allowed
     * @param {string} url - The URL to check
     * @returns {boolean} True if navigation is allowed, false otherwise
     */
    function isNavigationAllowed(url) {
        if (!isUrlBlocked(url)) {
            console.log('Navigation allowed to:', url);
            lastKnownGoodUrl = url;
            return true;
        } else {
            console.error('Blocked navigation to:', url);
            addToAutomatedBlacklist(url);
            if (lastKnownGoodUrl) {
                window.location.replace(lastKnownGoodUrl);
            }
            return false;
        }
    }

    const originalAssign = window.location.assign.bind(window.location);
    const originalOpen = window.open;

    console.log('Original window.location.assign and window.open saved.');

    window.location.assign = function(url) {
        console.log('Redirect attempt detected:', url);
        if (!allowedPopups.some(domain => url.includes(domain)) && !isNavigationAllowed(url)) {
            console.log('Redirect to undesired domain blocked:', url);
            return;
        }
        console.log('Redirect allowed to:', url);
        return originalAssign(url);
    };

    console.log('window.location.assign overridden with custom logic.');

    window.open = function(url, name, features) {
        console.log('Popup attempt detected:', url);
        if (allowedPopups.some(domain => url.includes(domain)) || isNavigationAllowed(url)) {
            console.log('Popup allowed for:', url);
            return originalOpen(url, name, features);
        }
        console.log('Blocked a popup from:', url);
        return null;
    };

    console.log('window.open overridden with custom logic.');

    let lastKnownGoodUrl = window.location.href;

    const locationProxy = new Proxy(window.location, {
        set(target, prop, value) {
            if (prop === 'href' || prop === 'assign' || prop === 'replace') {
                if (!isNavigationAllowed(value)) {
                    return false;
                }
            }
            return Reflect.set(target, prop, value);
        },
        get(target, prop) {
            if (prop === 'assign' || prop === 'replace') {
                return function(url) {
                    if (isNavigationAllowed(url)) {
                        return target[prop].call(target, url);
                    }
                };
            }
            return Reflect.get(target, prop);
        }
    });

    Object.defineProperty(window, 'location', {
        configurable: true,
        enumerable: true,
        get() {
            return locationProxy;
        }
    });

    window.addEventListener('popstate', function(event) {
        if (!isNavigationAllowed(window.location.href)) {
            console.error('Blocked navigation to:', window.location.href);
            history.pushState(null, "", lastKnownGoodUrl);
            window.location.replace(lastKnownGoodUrl);
            event.preventDefault();
        }
    });

    /**
     * Handle history manipulation
     * @param {Function} originalMethod - The original history method
     * @param {*} data - The state data
     * @param {string} title - The page title
     * @param {string|null} url - The URL
     * @returns {*} The result of calling the original method
     */
    function handleHistoryManipulation(originalMethod, data, title, url) {
        if (!isUrlBlocked(url)) {
            return originalMethod.call(history, data, title, url);
        }
        console.error('Blocked history manipulation to:', url);
    }

    const originalPushState = history.pushState;
    const originalReplaceState = history.replaceState;

    history.pushState = function(data, title, url) {
        return handleHistoryManipulation(originalPushState, data, title, url);
    };

    history.replaceState = function(data, title, url) {
        return handleHistoryManipulation(originalReplaceState, data, title, url);
    };

    /**
     * Check if a URL is blocked based on the blacklist
     * @param {string} url - The URL to check
     * @returns {boolean} True if the URL is blocked, false otherwise
     */
    function isUrlBlocked(url) {
        const encodedUrl = encodeURIComponent(url);
        const automatedBlacklist = getAutomatedBlacklist();
        const isBlocked = [...manualBlacklist, ...automatedBlacklist].some(blockedUrl => encodedUrl.includes(blockedUrl));
        if (isBlocked) {
            console.log(`Blocked URL: ${url}`);
        }
        return isBlocked;
    }

    console.log('Redirect control script with blacklist initialized.');
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址