Какой самый надежный способ скрыть/обмануть реферер в JavaScript?
Обычно реферер отслеживается через:
- JavaScript
document.referrer
- Заголовки запросов, например. PHP
$_SERVER['HTTP_REFERER']
Я установил демо-версию Codepad, которая показывает эти свойства для целей тестирования.
Требования:
- Исходный реферер должен быть эффективно скрыт, по крайней мере, для всех событий мыши.
- Поддержка кросс-браузера (по крайней мере, Chrome и Firefox).
- Автономный, без внешнего содержимого (плагины, библиотеки, страницы перенаправления,...).
- Никаких побочных эффектов: ссылки должны быть не переписаны, записи в истории должны быть сохранены.
Решение будет использовано, чтобы скрыть реферер, если следовать по ссылке <a href="url">
.
Точное описание прецедента
Как описано в этом вопросе на Webapps, ссылки в Google Поиске изменяются при нажатии. Следовательно,
- Google может отслеживать ваше поведение поиска (Privacy -)
- Запрос страницы немного задерживается.
- Связанная страница не может отслеживать ваш поисковый запрос Google (Privacy ++)
- Перетаскиваемые/скопированные URL-адреса выглядят как
http://google.com/lotsoftrash?url=actualurl
.
Я разрабатываю UserScript (Firefox)/Content script (Chrome) (code) который удаляет событие, искажающее связь с Google. В результате рассматриваются точки 1, 2 и 4.
Точка 3 остается.
- Chrome:
<a rel="noreferrer">
- Firefox:
data-URIs
. Я создал сложный подход для реализации этой функции для левого и среднего кликов, но все еще применяю пункт 4. Тем не менее, я борюсь с методом правого щелчка.
Ответы
Ответ 1
Я нашел решение, которое работает в Chrome и Firefox. Я реализовал код в Usercript, Не отслеживать меня Google.
Демо (протестировано в Firefox 9 и Chrome 17): http://jsfiddle.net/RxHw5/
Referrer скрывается для Webkit (Chrome,..) и Firefox 37+ (33 + *)
Webkit-браузеры (такие как Chrome, Safari) поддержка <a rel="noreferrer">
spec.
Скрытие ссылок может быть полностью реализовано путем объединения этого метода с двумя прослушивателями событий:
-
mousedown
. На клик, средний клик, контекстное меню контекстного меню,...
-
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].
Referrer скрывается для старых версий Firefox
Firefox не поддерживал rel="noreferrer"
до версии 33 ` [ошибка 530396] (или 37, если вы также хотите скрыть ссылку для контекстных меню).
URI данных + <meta http-equiv=refresh>
можно использовать для скрытия реферера в Firefox (и IE). Реализация этой функции сложнее, но также требует двух событий:
-
click
. При щелчке по среднему клику Enter
-
contextmenu
- щелкните правой кнопкой мыши, Tab Tab... Contextmenu
В Firefox событие click
запускается для каждого mouseup
и нажимает Enter на ссылку (или элемент управления формой). Событие contextmenu
требуется, поскольку событие click
срабатывает слишком поздно для этого случая.
Основываясь на URI данных и тайм-аутах с раздельной секундой:
Когда событие click
запускается, атрибут href
временно заменяется на URI данных. Событие завершено, и по умолчанию происходит: Открытие URI данных, в зависимости от атрибута target
и модификаторов SHIFT/CTRL.
Между тем, атрибут href
восстанавливается в исходное состояние.
Когда событие contextmenu
запускается, ссылка также изменяется на долю секунды.
- Параметры
Open Link in ...
откроют URI данных.
- Параметр
Copy Link location
относится к восстановленному исходному URI.
- ☹ Опция
Bookmark
относится к URI данных.
- ☹
Save Link as
указывает на 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" поддержки?.
Ответ 2
Невозможно создать систему ссылок, которая находится внутри iframes?
Если вы обмениваете iframe вокруг каждой ссылки, iframe может выступать в качестве внешнего de-refer. Пользователь будет щелкать по ссылке внутри фрейма, открывая страницу, чей реферер настроен на местоположение iFrame, а не на фактическую страницу.
Ответ 3
Как запрошено, используя JavaScript:
var meta = document.createElement('meta');
meta.name = "referrer";
meta.content = "no-referrer";
document.getElementsByTagName('head')[0].appendChild(meta);
Это добавит следующий метатег в раздел заголовка веб-страницы:
<meta name="referrer" content="no-referrer" />
Начиная с 2015 года, вы предотвращаете отправку заголовка Referer.
Ответ 4
В Javascript есть перекрестное решение для браузера, которое удаляет реферер, он использует динамические выражения iframes, вы можете взглянуть на доказательство концепции (отказ от ответственности: он использует небольшую библиотеку JS, которую я написал).
Ответ 5
Вы можете использовать новый проект стандартной политики Referrer, чтобы предотвратить отправку заголовка реферера в начало запроса. Пример:
<meta name="referrer" content="none">
Хотя Chrome и Firefox уже внедрили черновик версии политики реферера, вы должны быть осторожны с ним, потому что, например, Chrome ожидает no-referrer
вместо none
(и я также видел never
где-то). Я не знаю поведения, если вы просто добавляете три отдельных метатега, но в случае, если это не работает, вы все равно можете просто реализовать короткий script, который выполняет итерацию по всем трем значениям и проверяет, действительно ли значение было установлено после установки атрибут/свойство метатега.
Этот метатег применяется ко всем запросам на текущей странице (ajax, изображения, скрипты, другие ресурсы...) и навигации к другой странице.
Ответ 6
Это сложнее, чем может показаться на первый взгляд. Посмотрите на код этого проекта:
https://github.com/knu/noreferrer
He promises достаточно того, что вы хотите, но вы должны сделать это на странице ссылок.
Ответ 7
То, о чем вы просите, не может быть сделано в 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 // <----------------
});
},
Очевидно, что пользовательским скриптам не разрешается изменять реализацию контекстного меню, поэтому единственный выход - расширение браузера.
(Или, что было бы неплохим взломом, отключите контекстное меню, вызвав preventDefault()
в событии contextmenu
и используйте свое собственное контекстное меню)
Ответ 8
Весьма обширный (но короткий) анализ можно найти по адресу:
http://lincolnloop.com/blog/2012/jun/27/referrer-blocking-hard/
В этой статье анализируются оба метода, объясняемые в других ответах (метод js, перенаправление iframe) и, наконец, предлагаемый подход к вспомогательной странице редиректора, как тот, который встречается в ссылках поиска google.
Ответ 9
Я использовал простую, но эффективную версию 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);
Ответ 10
что, если мы отправим FORM с помощью JavaScript, таким образом не будет реферера.
document.form_name.submit()
в основном мы представляем форму с желаемым ACTION методом.