Stop Nefarious Redirects

Block unauthorized redirects and prevent history manipulation

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

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