Каков самый надежный способ скрыть / обмануть реферера в JavaScript?

обычно реферер отслеживается через:

    в JavaScript!--0-->
  • заголовки запросов, например PHP $_SERVER['HTTP_REFERER']

Я создал подсветка демо, который показывает эти свойства, для целей тестирования.

требования:

  1. исходный реферер должен быть эффективно скрыт, по крайней мере, для всех событий мыши.
  2. Кросс-браузерная поддержка (в минимум Chrome и Firefox).
  3. автономный, без какого-либо внешнего контента (Плагины, библиотеки, страницы перенаправления, ...).
  4. никаких побочных эффектов: ссылки должны не быть переписаны, записи истории должны быть сохранил.

решение будет использоваться для скрытия реферера при переходе по ссылке из <a href="url">.


точное описание использования

как описано в этот вопрос по Webapps, ссылки в Google Search изменяются по щелчку мыши. Следовательно,

  1. Google может отслеживать ваше поведение (конфиденциальность-- )
  2. запрос страницы немного задерживается.
  3. связанная страница не может отслеживать ваш поисковый запрос Google (конфиденциальность++ )
  4. Перетаскиваемые / скопированные URL-адреса выглядят как http://google.com/lotsoftrash?url=actualurl.

Я разрабатываю Userscript (Firefox) / скрипт контента (Chrome) (код), который удаляет событие искажения ссылок Google. В результате рассматриваются пункты 1, 2 и 4.

пункт 3 остается.

  • Chrome:<a rel="noreferrer">
  • Firefox:data-URIs. Я создал сложный подход для реализации этой функции для левого и среднего кликов, все еще применяя точку 4. тем не менее, я борюсь с правой кнопкой мыши метод.

10 ответов


я нашел решение, которое работает в Chrome и Firefox. Я реализовал код в Userscript,не отслеживать меня Google.

Demo (протестировано в Firefox 9 и Chrome 17): http://jsfiddle.net/RxHw5/

скрытие реферера для Webkit (Chrome, ..) и Firefox 37+ (33+*)

браузеры на основе Webkit (такие как Chrome, Safari) поддержка <a rel="noreferrer"> spec.
Скрытие реферера может быть полностью реализовано путем объединения этого метода с двумя прослушивателями событий:

  • mousedown - на щелчок, средний щелчок, щелкните правой кнопкой мыши contextmenu,...
  • keydown (Tab Tab Tab ... Enter).

код:

function hideRefer(e) {
   var a = e.target;
   // The following line is used to deal with nested elements,
   //  such as: <a href="."> Stack <em>Overflow</em> </a>.
   if (a && a.tagName !== 'A') a = a.parentNode;
   if (a && a.tagName === 'A') {
      a.rel = 'noreferrer';
   }
}
window.addEventListener('mousedown', hideRefer, true);
window.addEventListener('keydown', hideRefer, true);

* rel=noreferrer поддерживается в Firefox с 33, но поддержка была ограничена ссылками на странице. Рефереры все еще отправлялись, когда пользователь открывал вкладку через контекстное меню. Эта ошибка была исправлена в Firefox 37 [ошибка 1031264].

реферер скрывается для старых версий Firefox

Firefox не поддерживает rel="noreferrer" до версии 33 `[530396 ошибка] (или 37, Если вы хотите скрыть реферер для контекстных меню также).

"данные" -Ури + <meta http-equiv=refresh> может использоваться для скрытия реферера в Firefox (и IE). Реализация этой функции более сложна, но также требует двух событий:

  • click - по клику, по среднему клику, Enter
  • contextmenu-при щелчке правой кнопкой мыши,Tab Tab ... Contextmenu

в Firefox click событие для каждого mouseup и удара Enter по ссылке (или форма контроля). The contextmenu событие нужно, ведь click событие срабатывает слишком поздно для этого случая.

на основе данных-URIs и split-second тайм-аутов:
Когда click событие срабатывает,href атрибут временно заменяется на data-URI. Событие завершено, и происходит поведение по умолчанию: Открытие data-URI, зависящего от target атрибут и SHIFT / CTRL модификаторы.
Между тем,href атрибут восстанавливается в исходное состояние.

когда contextmenu событие запускается, ссылка также изменяется в течение доли секунды.

  • на Open Link in ... параметры откроют data-URI.
  • на Copy Link location опция относится к восстановленному, исходному URI.
  • ☹ в Bookmark опция относится к data-URI.
  • Save Link as указывает на data-URI.

код:

// Create a data-URI, redirection by <meta http-equiv=refresh content="0;url=..">
function doNotTrack(url) {
   // As short as possible. " can potentially break the <meta content> attribute,
   // # breaks the data-URI. So, escape both characters.
   var url = url.replace(/"/g,'%22').replace(/#/g,'%23');
   // In case the server does not respond, or if one wants to bookmark the page,
   //  also include an anchor. Strictly, only <meta ... > is needed.
   url = '<title>Redirect</title>'
       + '<a href="' +url+ '" style="color:blue">' +url+ '</a>'
       + '<meta http-equiv=refresh content="0;url=' +url+ '">';
   return 'data:text/html,' + url;
}
function hideRefer(e) {
   var a = e.target;
   if (a && a.tagName !== 'A') a = a.parentNode;
   if (a && a.tagName === 'A') {
      if (e.type == 'contextmenu' || e.button < 2) {
         var realHref = a.href; // Remember original URI
         // Replaces href attribute with data-URI
         a.href = doNotTrack(a.href);
         // Restore the URI, as soon as possible
         setTimeout(function() {a.href = realHref;}, 4);
      }
   }
}
document.addEventListener('click', hideRefer, true);
document.addEventListener('contextmenu', hideRefer, true);

сочетания обоих методов

к сожалению, нет простого способа функции-обнаружить эту функцию (не говоря уже об ошибках). Таким образом, вы можете выбрать соответствующий код на основе navigator.userAgent (т. е. UA-sniffing), или используйте один из запутанных методов обнаружения от как я могу обнаружить поддержку rel="noreferrer"?.


не можете ли вы создать систему ссылок, которая находится внутри iframes?

Если вы обертываете iframe вокруг каждой ссылки, iframe может выступать в качестве внешней ссылки. Пользователь нажимает на ссылку внутри фрейма, открывая страницу, чей реферер установлен в местоположение iFrame, а не фактическую страницу.


по запросу с помощью JavaScript:

var meta = document.createElement('meta');
meta.name = "referrer";
meta.content = "no-referrer";
document.getElementsByTagName('head')[0].appendChild(meta);

это добавит следующий метатег в раздел head веб-страницы:

<meta name="referrer" content="no-referrer" />

по состоянию на 2015 год вот как вы предотвращаете отправку заголовка Referer.


в Javascript есть кросс-браузерное решение, которое удаляет реферер, он использует iframes, созданные динамически, вы можете взглянуть на доказательство концепции (отказ от ответственности: он использует небольшую библиотеку JS, которую я написал ).


можно использовать тег стандартный проект политики реферера чтобы предотвратить отправку заголовка referer в источник запроса. Пример:

<meta name="referrer" content="none">

хотя Chrome и Firefox уже реализовали черновую версию политики реферера, вы должны быть осторожны с ней, потому что, например, Chrome ожидает no-referrer вместо none (и я также видел never где-то). Я не знаю поведения, если вы просто добавляете три отдельных мета-тега, но в случае, если это не работает, вы все равно можете просто реализовать короткий скрипт, который повторяет все три значения и проверяет, действительно ли значение было установлено после установки атрибута/свойства мета-тега.

этот мета-тег применяется ко всем запросам на текущей странице (ajax, изображения, скрипты, другие ресурсы...) и переход на другую страницу.


Это сложнее, чем может показаться на первый взгляд. Посмотрите на код этого проекта:

https://github.com/knu/noreferrer

Он обещает то, что вы хотите, но вы должны сделать это на странице ссылки.


то, что вы просите не может быть сделано в Firefox.

на текущая реализация контекстного меню всегда передает текущий документ в качестве реферера:

// Open linked-to URL in a new window.
openLink: function () {
    var doc = this.target.ownerDocument;
    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
    openLinkIn(this.linkURL, "window", {
        charset: doc.characterSet,
        referrerURI: doc.documentURIObject // <----------------
    });
},

// Open linked-to URL in a new tab.
openLinkInTab: function () {
    var doc = this.target.ownerDocument;
    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
    openLinkIn(this.linkURL, "tab", {
        charset: doc.characterSet,
        referrerURI: doc.documentURIObject // <----------------
    });
},

// open URL in current tab
openLinkInCurrent: function () {
    var doc = this.target.ownerDocument;
    urlSecurityCheck(this.linkURL, doc.nodePrincipal);
    openLinkIn(this.linkURL, "current", {
        charset: doc.characterSet,
        referrerURI: doc.documentURIObject // <----------------
    });
}, 

очевидно, что userscripts не разрешено изменять реализацию контекстного меню, поэтому единственным выходом является расширение браузера.

(или, что было бы довольно плохим взломом, отключите контекстное меню, вызвав preventDefault() на contextmenu событие и используйте свой собственный контекст меню)


очень полный (но короткий) анализ можно найти по адресу:

http://lincolnloop.com/blog/2012/jun/27/referrer-blocking-hard/

в этой статье анализируются оба метода, объясненные в других ответах (метод js, перенаправление iframe), и, наконец, предлагают опосредованный подход к странице перенаправления, подобный тому, который наблюдается в ссылках поиска google.


я реализовал простое, но эффективное решение iframe с использованием jquery.

https://jsfiddle.net/skibulk/0oebphet/

(function($){
  var f = $('<iframe src="about:blank" style="display: none !important;">').appendTo('body');
  $('a[rel~=noreferrer]').click(function(event){
    var a = $(event.target.outerHTML);
    a.appendTo(f.contents().find('body'));
    a[0].click();
    return false;
  });
})(jQuery);

что делать, если мы отправим форму с помощью JavaScript, таким образом, не будет реферера.

document.form_name.submit()

в основном мы представляем форму с желаемым действие метод.