Stop Nefarious Redirects

Block unauthorized redirects and prevent history manipulation

当前为 2024-05-07 提交的版本,查看 最新版本

  1. javascript
  2. // ==UserScript==
  3. // @name Stop Nefarious Redirects
  4. // @namespace http://tampermonkey.net/
  5. // @version 3.82
  6. // @description Block unauthorized redirects and prevent history manipulation
  7. // @match http://*/*
  8. // @match https://*/*
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license MIT
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Function to get the current blacklist
  19. function getBlacklist() {
  20. return new Set(GM_getValue('blacklist', []));
  21. }
  22.  
  23. // Function to add a URL to the blacklist
  24. function addToBlacklist(url) {
  25. let blacklist = getBlacklist();
  26. if (!blacklist.has(url)) {
  27. blacklist.add(url);
  28. GM_setValue('blacklist', Array.from(blacklist));
  29. }
  30. }
  31.  
  32. // Function to display the blacklist
  33. function displayBlacklist() {
  34. let blacklist = getBlacklist();
  35. console.log('Current Blacklist:\n' + Array.from(blacklist).join('\n'));
  36. }
  37.  
  38. // Debounce function
  39. function debounce(func, delay) {
  40. let timeoutId;
  41. return function(...args) {
  42. clearTimeout(timeoutId);
  43. timeoutId = setTimeout(() => func.apply(this, args), delay);
  44. };
  45. }
  46.  
  47. // Function to handle navigation events
  48. const handleNavigation = debounce(function(url) {
  49. try {
  50. if (!isUrlAllowed(url)) {
  51. console.error('Blocked navigation to:', url);
  52. addToBlacklist(url); // Add the unauthorized URL to the blacklist
  53. if (lastKnownGoodUrl) {
  54. window.location.replace(lastKnownGoodUrl);
  55. }
  56. return false;
  57. } else {
  58. console.log('Navigation allowed to:', url);
  59. lastKnownGoodUrl = url;
  60. return true;
  61. }
  62. } catch (error) {
  63. console.error('Error in handleNavigation:', error);
  64. }
  65. }, 100);
  66.  
  67. let lastKnownGoodUrl = window.location.href;
  68. let navigationInProgress = false;
  69.  
  70. // Monitor changes to window.location
  71. ['assign', 'replace', 'href'].forEach(property => {
  72. const original = window.location[property];
  73. if (typeof original === 'function') {
  74. window.location[property] = function(url) {
  75. if (!navigationInProgress && handleNavigation(url)) {
  76. navigationInProgress = true;
  77. setTimeout(() => {
  78. navigationInProgress = false;
  79. }, 0);
  80. return original.apply(this, arguments);
  81. }
  82. };
  83. } else {
  84. Object.defineProperty(window.location, property, {
  85. set: function(url) {
  86. if (!navigationInProgress && handleNavigation(url)) {
  87. navigationInProgress = true;
  88. setTimeout(() => {
  89. navigationInProgress = false;
  90. }, 0);
  91. return Reflect.set(window.location, property, url);
  92. }
  93. },
  94. get: function() {
  95. return original;
  96. },
  97. configurable: true
  98. });
  99. }
  100. });
  101.  
  102. // Enhanced navigation control for back/forward buttons
  103. window.addEventListener('popstate', function(event) {
  104. if (!navigationInProgress && !isUrlAllowed(window.location.href)) {
  105. navigationInProgress = true;
  106. setTimeout(() => {
  107. navigationInProgress = false;
  108. }, 0);
  109. event.preventDefault();
  110. }
  111. });
  112.  
  113. // Function to handle history manipulation
  114. function handleHistoryManipulation(originalMethod, data, title, url) {
  115. if (!isUrlAllowed(url)) {
  116. console.error('Blocked history manipulation to:', url);
  117. return;
  118. }
  119. return originalMethod(data, title, url);
  120. }
  121.  
  122. // Wrap history.pushState and history.replaceState
  123. const originalPushState = history.pushState;
  124. const originalReplaceState = history.replaceState;
  125.  
  126. history.pushState = function(data, title, url) {
  127. return handleHistoryManipulation.call(history, originalPushState.bind(this), data, title, url);
  128. };
  129.  
  130. history.replaceState = function(data, title, url) {
  131. return handleHistoryManipulation.call(history, originalReplaceState.bind(this), data, title, url);
  132. };
  133.  
  134. // Keyboard shortcut listener to display the blacklist
  135. document.addEventListener('keydown', function(e) {
  136. if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 'l') {
  137. e.preventDefault();
  138. displayBlacklist();
  139. }
  140. });
  141.  
  142. // Function to check if a URL is allowed based on the blacklist
  143. function isUrlAllowed(url) {
  144. let blacklist = getBlacklist();
  145. return !blacklist.has(url);
  146. }
  147.  
  148. console.log('Redirect control script with blacklist initialized.');
  149. })();