12k
All articles

Warum rel='noopener' bei Links obsolet ist

Warum rel=noopener für target=_blank-Links obsolet ist, was Reverse Tabnabbing war und wann noreferrer, opener oder COOP noch wichtig sind.

OpenReplay Team
OpenReplay Team
Warum rel='noopener' bei Links obsolet ist

Bei einem einfachen target="_blank"-Link ist rel="noopener" inzwischen redundant: Alle aktuellen Versionen von Chrome, Edge, Firefox und Safari wenden das noopener-Verhalten automatisch an, sodass ein bloßes target="_blank" window.opener bereits auf null setzt.

Wenn Sie es aus Gewohnheit immer noch hinschreiben oder zusehen, wie der Linter genau jenen Anchor markiert, den Sie vergessen haben, flicken Sie ein Loch, das der Browser vor Jahren geschlossen hat. Dieser Artikel erläutert, welche Schwachstelle damit verhindert werden sollte, wann die Browser die Korrektur zum Standard machten und in welchen konkreten Fällen rel weiterhin echte Arbeit leistet: noreferrer (nicht automatisch), rel="opener" (bewusstes Zurückschalten) und der Cross-Origin-Opener-Policy-Header für site-weite Kontrolle.

Die wichtigsten Erkenntnisse

  • In modernen Browsern setzt ein bloßes target="_blank" window.opener bereits auf null; das manuelle Hinzufügen von rel="noopener" ist damit lediglich Defense-in-Depth für ein Loch, das der Browser ohnehin schon geschlossen hat.
  • Das implizite noopener wurde stufenweise ausgeliefert (Safari 2018–19, Firefox 79 Mitte 2020, Chromium 88 Anfang 2021) und ist inzwischen Teil des WHATWG-HTML-Standards.
  • Laut caniuse.com deckt das implizite noopener rund 95 % der globalen Browsernutzung ab.
  • noreferrer ist nicht implizit: Es entfernt weiterhin den Referer-Header und impliziert zugleich noopener – setzen Sie es also nur dann ein, wenn Sie Referrer-Datenschutz wünschen.
  • Verwenden Sie rel="opener", um window.opener bewusst wieder zu aktivieren, und Cross-Origin-Opener-Policy: same-origin, um die Opener-Verknüpfung für ein gesamtes Dokument an einer zentralen Stelle zu kappen.

Das ursprüngliche Problem: Reverse Tabnabbing

Bevor die Browser den Standard änderten, übergab ein target="_blank"-Link der neu geöffneten Seite eine aktive Referenz zurück auf die Seite, die sie geöffnet hatte. Reverse Tabnabbing ist der Angriff, der dies ausnutzt: Die Zielseite liest window.opener und leitet den ursprünglichen Tab auf einen Phishing-Klon um, während die Aufmerksamkeit des Nutzers auf dem neuen Tab liegt. Mathias Bynens’ kanonische Erklärung des Problems bringt es klar auf den Punkt: Wo immer window.opener existiert, kann die geöffnete Seite den Opener anderswohin lenken – unabhängig davon, zu welcher Origin die beiden Seiten gehören.

Der Exploit ist ein Einzeiler, der im geöffneten Dokument läuft:

if (window.opener) {
  window.opener.location = 'https://you-re-hacked.com';
}

Das entscheidende Detail: Das funktioniert über Origin-Grenzen hinweg. Das Lesen und Schreiben von window.opener.location wird nicht blockiert, wenn die beiden Seiten von unterschiedlichen Hosts stammen – weder die Same-Origin-Policy noch CORS verhindern also, dass der Opener umgeleitet wird. Damit war es überall dort gefährlich, wo Sie nutzergenerierte oder Drittanbieter-Links ausgegeben haben (Foren, Kommentare, Profilfelder) und ein Angreifer die Kontrolle über das href hatte.

Was sich geändert hat: target="_blank" impliziert nun rel="noopener"

Die Browser haben den Standard korrigiert. Bei <a>-, <area>- und <form>-Elementen hat ein target="_blank" heute dieselbe Wirkung, als würden Sie selbst rel="noopener" schreiben: Das geöffnete Dokument erhält null von window.opener zurück, ohne dass ein Attribut nötig ist. Dieses Verhalten ist in der WHATWG-HTML-Spezifikation festgeschrieben, deren Regeln zum Folgen eines Hyperlinks jedes _blank-Target als noopener behandeln, sofern der Link nicht mittels rel="opener" explizit abweicht. OWASP verweist inzwischen auf genau diesen standardisierten Default und betrachtet den Angriff auf Evergreen-Browsern als weitgehend geschlossen.

Die Umstellung erstreckte sich über etwa drei Jahre – „moderne Browser machen das” ist also eine Zeitleiste, kein einzelnes Datum:

EngineErste Stable-Version mit implizitem noopenerUngefährer Auslieferungszeitpunkt
Safari / WebKitSafari 12.1 (Vorschau in Tech Preview 68)Ende 2018 – 2019
Firefox / GeckoFirefox 79Mitte 2020
Chromium (Chrome, Edge)Chrome/Edge 88Anfang 2021

Beachten Sie: Diese Versionen beschreiben das implizite Verhalten, nicht den Zeitpunkt, ab dem das Attribut rel="noopener" selbst unterstützt wurde. Das war Jahre früher der Fall und ist ein anderer Meilenstein. Die Caniuse-Tabelle zum impliziten noopener beziffert die globale Unterstützung auf rund 95 %, wobei Evergreen-Browser seit etwa 2018 abgedeckt sind. Der verbleibende Anteil ist klein, aber real – prüfen Sie also Ihre eigenen Analytics-Daten, bevor Sie das Attribut entfernen. Der bemerkenswerte Nachzügler ist das alte Edge auf Nicht-Chromium-Basis.

„Obsolet zum manuellen Hinzufügen” ist nicht dasselbe wie „nutzlos”

Dass rel="noopener" als Tippaufwand redundant ist, macht das gesamte rel-Attribut nicht überflüssig. Automatisch ist nun konkret das Keyword noopener. Die anderen verändern das Verhalten weiterhin:

KeywordWirkungMuss man es 2026 noch schreiben?
noopenerSetzt window.opener in der geöffneten Seite auf nullNein, implizit bei target="_blank"
noreferrerEntfernt den Referer-Header und impliziert noopenerNur, wenn Sie Referrer-Datenschutz wünschen
openerStellt window.opener wieder her (bewusstes Zurückschalten)Ja, wenn Sie die Referenz tatsächlich benötigen

noreferrer ist nicht implizit. Es unterdrückt weiterhin den Referer-Header – fügen Sie es also nur hinzu, wenn Sie die Ursprungs-URL tatsächlich vor der Zielseite zurückhalten wollen. Den Sicherheitsvorteil bringt es gratis mit: Da noreferrer auch den Opener auf null setzt, bringt ein zusätzliches noopener daneben keinen Nutzen. Damit ist die verbreitete Kombination rel="noopener noreferrer" in modernen Browsern doppelt redundant, denn noreferrer allein deckt beide Aspekte ab.

Wenn Sie wirklich möchten, dass die geöffnete Seite ihre window.opener-Referenz behält (etwa ein Popup, das eine Nachricht zurücksendet), aktivieren Sie das explizit mit rel="opener". Die WebKit-Release-Notes, die die Änderung eingeführt haben, beschreiben es genauso: Das sichere Verhalten ist nun der Default, und rel="opener" ist der Weg, es bewusst umzukehren.

Ein ehrlicher Vorbehalt zur Unterstützung älterer Umgebungen: rel="noopener" trotzdem hinzuzufügen, ist harmlos. Die Dokumentation des Lighthouse-Audits von Chrome weist darauf hin, dass das explizite Ausschreiben des Attributs weiterhin ein gewisses Maß an Absicherung für alle bietet, die auf einer älteren Engine wie Edge Legacy festhängen. In modernen Browsern ist es Rauschen, aber falsch ist es nicht.

COOP: die skalierbare, site-weite Steuerung

Um die Weitergabe von window.opener für ein gesamtes Dokument an einer Stelle zu kappen, senden Sie den Response-Header Cross-Origin-Opener-Policy: same-origin, anstatt jeden einzelnen Link zu dekorieren. Der Cross-Origin-Opener-Policy-Header (COOP) entscheidet, ob ein neu geöffnetes Top-Level-Dokument Ihrer Browsing-Kontext-Gruppe beitritt oder eine eigene erhält. Bei same-origin landen Cross-Origin-Dokumente in einer separaten Gruppe, und die Referenzen zwischen ihnen und ihrem Opener werden getrennt – der Opener-Kanal wird also einmal und zentral geschlossen, nicht pro Anchor.

# nginx
add_header Cross-Origin-Opener-Policy "same-origin";
// Express
app.use((req, res, next) => {
  res.set('Cross-Origin-Opener-Policy', 'same-origin');
  next();
});

Eine Einschränkung: COOP wird ausschließlich als HTTP-Response-Header ausgeliefert. Es gibt kein Äquivalent per <meta http-equiv> – wenn Sie in Ihrer Infrastruktur keine Response-Header setzen können, können Sie COOP also nicht anwenden. In aktuellen Browsern ist es breit unterstützt und als Defense-in-Depth durchaus lohnend. Ein Session Replay eines echten Nutzers, der auf einen externen target="_blank"-Link klickt, ist ein praktischer Weg, um zu bestätigen, dass der ursprüngliche Tab nie navigiert wurde – und um jede Meldung über unerwartete Navigation exakt in dem Browser zu reproduzieren, den der Nutzer verwendet hat.

Das Fazit: Was jetzt zu tun ist

Fügen Sie in neuem Code für moderne Browser rel="noopener" nicht manuell hinzu; der Browser setzt es für Sie. Sie können Lint-Regeln, die es bei jedem target="_blank" erzwingen – etwa react/jsx-no-target-blank –, bedenkenlos lockern; behalten Sie die Regel nur dann aktiv, wenn Sie Edge Legacy oder andere Engines von vor 2021 abdecken müssen. Setzen Sie rel="noreferrer" genau dann, wenn Sie den Referer-Header unterdrücken wollen. Verwenden Sie rel="opener" in dem seltenen Fall, dass Sie die Opener-Referenz zurückbenötigen. Für eine skalierbare, dokumentweite Garantie senden Sie Cross-Origin-Opener-Policy: same-origin.

Erwähnenswert: Frühere Empfehlungen – darunter OpenReplays eigener älterer Beitrag, der rel="noreferrer noopener" für jeden Link empfiehlt – behandeln noopener als etwas, das man immer schreiben muss, und berücksichtigen den impliziten Default nicht. Das spiegelt eine Gewohnheit wider, an der die Branche noch lange festhielt, nachdem die Browser weitergezogen waren. Die zutreffende Position im Jahr 2026 ist enger gefasst: noopener ist inzwischen der Default, sein manuelles Hinzufügen also obsolet – während noreferrer, rel="opener" und COOP jeweils weiterhin eine eigene Aufgabe erfüllen. Greifen Sie bewusst zu diesen Mitteln und lassen Sie den Rest den Browser erledigen.

FAQs

Beinhaltet rel='noreferrer' auch rel='noopener'?

Ja. Das Setzen von rel='noreferrer' impliziert automatisch rel='noopener', sodass window.opener zusätzlich zum Entfernen des Referer-Headers auf null gesetzt wird. Das bedeutet, dass die verbreitete Kombination rel='noopener noreferrer' in modernen Browsern doppelt redundant ist: noreferrer allein deckt sowohl das Nullen des Openers als auch die Unterdrückung des Referrers ab. Fügen Sie noreferrer nur dann hinzu, wenn Sie die Ursprungs-URL tatsächlich vor der Zielseite zurückhalten wollen.

Was passiert, wenn ich rel='noopener' bei einem target='_blank'-Link heute vollständig weglasse?

In modernen Browsern nichts Gefährliches. Ein bloßes target='_blank' setzt window.opener bereits auf null, weil Chrome, Edge, Firefox und Safari das noopener-Verhalten implizit anwenden – eine Regel, die im WHATWG-HTML-Standard kodifiziert ist. Caniuse beziffert das auf rund 95 % der globalen Browsernutzung. Reverse Tabnabbing ist standardmäßig wirkungslos; die einzige Lücke sind Legacy-Engines wie das Nicht-Chromium-basierte Edge Legacy.

Kann ich Cross-Origin-Opener-Policy per Meta-Tag statt per Header setzen?

Nein. COOP wird ausschließlich als HTTP-Response-Header ausgeliefert, und es gibt kein Äquivalent per meta http-equiv. Wenn Ihre Infrastruktur keine Response-Header setzen kann, können Sie COOP nicht anwenden und müssen auf rel-Attribute pro Link oder den impliziten noopener-Default zurückgreifen. Wenn Sie Header setzen können, kappt das Senden von Cross-Origin-Opener-Policy: same-origin die Weitergabe von window.opener für ein gesamtes Dokument an einer zentralen Stelle, anstatt jeden Anchor zu dekorieren.

Wie aktiviere ich window.opener wieder, wenn ich es tatsächlich brauche?

Setzen Sie rel='opener' explizit auf den Link. Da das sichere Verhalten – window.opener auf null zu setzen – nun der Browser-Default ist, stellen Sie die Opener-Referenz mit rel='opener' bewusst wieder her, beispielsweise wenn ein Popup eine Nachricht an die Seite zurücksenden muss, die es geöffnet hat. Das kehrt das implizite noopener-Verhalten für diesen konkreten Link um, ohne andere zu beeinflussen.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.