it-swarm.com.de

Was ist der zuverlässigste Weg, um den Verweis in JavaScript zu verbergen/zu fälschen?

Normalerweise ist der Referrer nachvollziehbar durch:

  • JavaScript's document.referrer
  • Die Anforderungsheader, z. PHP's $_SERVER['HTTP_REFERER']

Ich habe ein Codepad Demo eingerichtet, das diese Eigenschaften zu Testzwecken zeigt.

Bedarf:

  1. Der ursprüngliche Verweis sollte zumindest für alle Mausereignisse effektiv ausgeblendet sein.
  2. Browserübergreifende Unterstützung (mindestens Chrome und Firefox).
  3. Standalone, ohne externen Inhalt (Plugins, Bibliotheken, Weiterleitungsseiten, ...).
  4. Keine Nebeneffekte: Verknüpfungen sollten nicht überschrieben werden, Historieneinträge sollten beibehalten sein.

Die Lösung wird verwendet, um den Verweis auszublenden, wenn Sie einem Link von <a href="url"> folgen.


Genaue Beschreibung des Anwendungsfalls

Wie in diese Frage in Webapps beschrieben, werden Links in der Google-Suche durch Klicken geändert. Folglich,

  1. Google kann Ihr Suchverhalten nachverfolgen (Datenschutz--)
  2. Die Seitenanfrage wird etwas verzögert.
  3. Die verlinkte Seite kann Ihre Google-Suchabfrage nicht verfolgen (Privacy ++).
  4. Verschobene/kopierte URLs sehen wie http://google.com/lotsoftrash?url=actualurl aus.

Ich entwickle ein Userscript (Firefox)/Inhaltsskript (Chrome) ( code ), wodurch das link-verstümmelnde Ereignis von Google entfernt wird. Daher werden die Punkte 1, 2 und 4 behandelt.

Punkt 3 bleibt bestehen.

  • Chrome: <a rel="noreferrer">
  • Firefox: data-URIs . Ich habe einen ausgeklügelten Ansatz entwickelt, um diese Funktion für Links- und Mittelklicks zu implementieren, während Punkt 4 weiterhin durchgesetzt wird. Allerdings habe ich Schwierigkeiten mit der Rechtsklick-Methode.
40
Rob W

Ich habe eine Lösung gefunden, die in Chrome und Firefox funktioniert. Ich habe den Code in ein Userscript implementiert, Verfolge mich nicht mit Google.

Demo (getestet in Firefox 9 und Chrome 17): http://jsfiddle.net/RxHw5/

Referrer versteckt für Webkit (Chrome, ..) und Firefox 37+ (33 + *)

Webkit-basierte Browser (wie Chrome, Safari) nterstützung<a rel="noreferrer">spec.
Das Ausblenden von Verweisen kann vollständig implementiert werden, indem diese Methode mit zwei Ereignis-Listenern kombiniert wird:

  • mousedown - Klicken Sie mit der rechten Maustaste auf das Kontextmenü, ...
  • keydown (TabTabTab ... Enter).

Code:

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 wird in Firefox seit 33 unterstützt, die Unterstützung war jedoch auf seiteninterne Links beschränkt. Verweise wurden noch gesendet, als der Benutzer die Registerkarte über das Kontextmenü öffnete. Dieser Fehler wurde in Firefox 37 behoben [ Fehler 1031264 ].

Verweis versteckt für alte Firefox-Versionen

Firefox unterstützte rel="noreferrer" erst in Version 33 `[ Fehler 530396 ] (oder 37, wenn Sie den Referrer auch für Kontextmenüs ausblenden möchten).

Ein Daten-URI + <meta http-equiv=refresh> kann verwendet werden, um den Referrer in Firefox (und IE) auszublenden. Die Implementierung dieser Funktion ist komplizierter, erfordert jedoch auch zwei Ereignisse:

  • click - Beim Klicken, beim Mittelklicken, Enter
  • contextmenu - Klicken Sie mit der rechten Maustaste, TabTab ... Contextmenu

In Firefox wird das Ereignis click für jeden Treffer von mouseup und ausgelöst Enter auf einem Link (oder Formularsteuerelement). Das Ereignis contextmenu ist erforderlich, da das Ereignis click für diesen Fall zu spät ausgelöst wird.

Basierend auf Daten-URIs und Sekundenbruchteilen:
Wenn das Ereignis click ausgelöst wird, wird das Attribut href vorübergehend durch einen Daten-URI ersetzt. Das Ereignis ist beendet und das Standardverhalten tritt ein: Öffnen des Daten-URI, abhängig vom Attribut target und den SHIFT/CTRL-Modifikatoren.
Währenddessen wird das Attribut href in den ursprünglichen Zustand zurückversetzt.

Wenn das Ereignis contextmenu ausgelöst wird, ändert sich die Verknüpfung auch für den Bruchteil einer Sekunde.

  • Die Open Link in ... -Optionen öffnen den Daten-URI.
  • Die Option Copy Link location bezieht sich auf den wiederhergestellten ursprünglichen URI.
  • ☹ Die Option Bookmark bezieht sich auf den Daten-URI.
  • Save Link as zeigt auf den Daten-URI.

Code:

// 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);

Beide Methoden kombinieren

Leider gibt es keine einfache Möglichkeit, diese Funktion zu erkennen (geschweige denn Fehler zu berücksichtigen). Sie können also entweder den relevanten Code basierend auf navigator.userAgent (d. H. UA-Sniffing) auswählen oder eine der gewundenen Erkennungsmethoden aus Wie kann ich die Unterstützung von rel = "noreferrer" erkennen? verwenden.

40
Rob W

Können Sie kein Verknüpfungssystem erstellen, das sich innerhalb von Iframes befindet?

Wenn Sie einen iframe um jeden Link wickeln, kann der iframe als externe De-Referenz fungieren. Der Benutzer klickt auf den Link innerhalb des Frames und öffnet eine Seite, deren Referrer auf die Position des iFrame anstelle der eigentlichen Seite gesetzt ist.

10
fmsf

Auf Wunsch mit JavaScript:

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

Dadurch wird das folgende Meta-Tag zum Kopfbereich der Webseite hinzugefügt:

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

Ab 2015 So verhindern Sie das Senden des Referer-Headers.

6
MarcG

Es gibt eine Cross-Browser-Lösung in Javascript, die den Referrer entfernt, er verwendet dynamisch erzeugte Iframes. Sie können einen Blick auf ein proof of concept werfen (Disclaimer: Es wird eine kleine JS-Bibliothek verwendet, die ich geschrieben habe).

3
jpgerek

Sie können den neuen Standardentwurf für die Referrer-Richtlinie verwenden, um zu verhindern, dass der Referrer-Header an die Anforderung Origin gesendet wird. Beispiel:

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

Obwohl Chrome und Firefox bereits eine Entwurfsversion der Verweisrichtlinie implementiert haben, sollten Sie vorsichtig damit umgehen, da beispielsweise Chrome no-referrer anstelle von none erwartet (und ich habe auch never irgendwo gesehen). Ich kenne das Verhalten nicht, wenn Sie nur drei separate Meta-Tags hinzufügen. Wenn dies nicht funktioniert, können Sie dennoch ein kurzes Skript implementieren, das alle drei Werte durchläuft und überprüft, ob der Wert wirklich festgelegt wurde, nachdem das Attribut gesetzt wurde Eigenschaft des Meta-Tags.

Dieses Meta-Tag gilt für alle Anforderungen auf der aktuellen Seite (Ajax, Bilder, Skripts, andere Ressourcen ...) und die Navigation zu einer anderen Seite.

3
Joel Richard

Das, wonach Sie fragen, ist in Firefox nicht möglich.

Die aktuelle Kontextmenü-Implementierung übergibt immer das aktuelle Dokument als Referrer:

// 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 // <----------------
    });
}, 

Offensichtlich dürfen Benutzerskripte die Implementierung des Kontextmenüs nicht ändern. Der einzige Ausweg ist eine Browsererweiterung.

(Oder, was ein ziemlich schlechter Hack wäre, deaktivieren Sie das Kontextmenü, indem Sie preventDefault() für das Ereignis contextmenu aufrufen und verwenden Sie Ihr eigenes benutzerdefiniertes Kontextmenü.

1

Das ist schwieriger als es auf den ersten Blick erscheinen mag. Schauen Sie sich den Code dieses Projekts an:

https://github.com/knu/noreferrer

Er verspricht genau das, was Sie wollen, aber Sie müssen es auf der Verlinkungsseite tun.

1
Boldewyn

Eine sehr umfassende (aber kurze) Analyse finden Sie unter:

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

dieser Artikel analysiert beide Methoden, die in anderen Antworten erläutert wurden (js-Methode, iframe-umleitung), und schlägt schließlich einen Mediate-Redirector-Seitenansatz vor, wie er bei Google-Suchlinks zu finden ist.

1
Amir Ali Akbari

Ich habe eine einfache, aber effektive Iframe-Lösung mit Jquery implementiert.

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);
0
skibulk