// ==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.');
})();