Atrybut rel="noopener" to prosty, ale bardzo ważny mechanizm ochrony przed atakiem reverse tabnabbing, który wykorzystuje sposób działania linków otwieranych w nowej karcie (target="_blank"). Dodanie tego atrybutu odcina nowo otwartą kartę od dostępu do strony, z której została otwarta, eliminując możliwość podmiany jej zawartości w celu phishingu.
Skąd w ogóle problem? Linki w nowej karcie a bezpieczeństwo
W świecie tworzenia stron WWW powszechną praktyką jest otwieranie części linków w nowych kartach za pomocą target="_blank" – np. przy linkach zewnętrznych, do dokumentów PDF czy stron partnerów.
Technicznie wygląda to tak:
<a href="https://example.com" target="_blank">Otwórz w nowej karcie</a>
Dla użytkownika takie zachowanie jest wygodne, ale od strony bezpieczeństwa otwiera drogę do specyficznego ataku socjotechnicznego, znanego jako reverse tabnabbing.
Czym jest tabnabbing / reverse tabnabbing?
Tabnabbing (często precyzyjniej: reverse tabnabbing) to atak, w którym złośliwa strona otwarta w nowej karcie próbuje przejąć kontrolę nad kartą, z której została otwarta.
Typowy scenariusz:
- Użytkownik odwiedza Twoją stronę (np. panel logowania do banku lub konta w serwisie).
- Na stronie znajduje się link z
target="_blank"prowadzący do zewnętrznej domeny. - Użytkownik klika link → otwiera się nowa karta z nową stroną (np. pozornie nieszkodliwy blog, artykuł, zasób).
- Ta zewnętrzna strona, korzystając z obiektu
window.opener, uzyskuje dostęp do karty „rodzica” – Twojej strony. - Złośliwy skrypt podmienia adres w karcie rodzica (np. na fałszywą stronę logowania łudząco podobną do oryginału).
- Użytkownik wraca do pierwotnej karty (np. po przeczytaniu artykułu) i widzi „logowanie do swojego banku” – ale w rzeczywistości trafił na stronę atakującego.
Ponieważ użytkownik wciąż jest w „tej samej” karcie, w której wcześniej naprawdę widział zaufaną stronę, dużo łatwiej go oszukać i skłonić do podania danych logowania.
window.opener – klucz do ataku
Sednem problemu jest obiekt window.opener.
Gdy otwierasz stronę w nowej karcie (target="_blank"), przeglądarka w nowo otwartej karcie ustawia window.opener na obiekt reprezentujący stronę-rodzica (kartę, z której kliknięto link). Dzięki temu nowa karta może odwoływać się do rodzica, np. zmieniając adres URL.
window.opener.location = 'https://fałszywy-serwis.test';
To powoduje zmianę adresu w karcie rodzica. Właśnie ta możliwość modyfikacji window.opener.location jest wykorzystywana w tabnabbingu.
Istotne jest to, że do ataku wystarczy możliwość przekierowania rodzica (zmiana location), a nie pełen dostęp do jego DOM-u, więc przeglądarkowe mechanizmy same-origin policy nie zawsze tutaj pomagają.
Atrybut rel="noopener" – jak działa
rel="noopener" to wartość atrybutu rel w znaczniku <a>, której głównym zadaniem jest odcięcie nowej karty od dostępu do window.opener.
Mówiąc prościej: bez noopener nowa karta ma dostęp do window.opener i może manipulować kartą rodzica; z noopener przeglądarka ustawia window.opener w nowej karcie na null, więc nie da się odwołać do karty rodzica ani jej przejąć.
Kod:
<a href="https://example.com" target="_blank" rel="noopener">Zobacz stronę partnera</a>
W praktyce oznacza to: nowo otwarta strona nie może wywołać window.opener.location = ..., a próba dostępu do window.opener zwróci null lub będzie zablokowana.
rel="noopener" skutecznie eliminuje ryzyko reverse tabnabbingu związanego z daną kombinacją target="_blank" + link do zewnętrznej strony.
rel="noreferrer" a rel="noopener" – czym się różnią?
Często spotkasz zalecenie używania obu wartości naraz: rel="noopener noreferrer".
Działanie: noopener odcina dostęp do window.opener (blokuje możliwość manipulacji kartą rodzica), a noreferrer dodatkowo blokuje przesyłanie nagłówka Referer do strony docelowej – dzięki czemu nie dowie się ona, z jakiego dokładnie adresu przyszedł użytkownik.
Oba atrybuty można łączyć:
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Otwórz w nowej karcie</a>
W praktyce: jeśli zależy Ci wyłącznie na ochronie przed tabnabbingiem, wystarczy rel="noopener"; jeśli dodatkowo chcesz ukryć źródło ruchu (np. z powodów prywatności lub polityki serwisu), stosuj rel="noopener noreferrer".
Przykład ataku i jego zablokowania
Przykład podatnego linku (bez zabezpieczeń) –
<a href="https://example.com" target="_blank">Kliknij, aby zobaczyć ofertę</a>
W nowo otwartej karcie złośliwy skrypt może zrobić:
// kod w nowo otwartej karcie
if (window.opener) {
window.opener.location = 'https://fałszywa-strona-logowania.test';
}
Efekt: karta rodzica zostaje przekierowana na stronę atakującego.
Ten sam link z zabezpieczeniem –
<a href="https://example.com" target="_blank" rel="noopener">Kliknij, aby zobaczyć ofertę</a>
Teraz w nowej karcie:
console.log(window.opener); // null
Skrypt nie jest w stanie przejąć kontroli nad pierwotną kartą, więc atak tabnabbing nie zadziała.
Stan w nowoczesnych przeglądarkach (aktualizacja OWASP)
Według aktualnych materiałów OWASP, nowoczesne, „evergreenowe” przeglądarki (regularnie aktualizowane) domyślnie traktują linki z target="_blank" jakby miały ustawione rel="noopener".
OWASP podkreśla, że w tych przeglądarkach podatność na reverse tabnabbing nie jest już tak powszechna i krytyczna jak dawniej, bo mechanizm jest automatycznie blokowany. Jednocześnie w oficjalnych wytycznych testowania bezpieczeństwa OWASP nadal zaleca, aby wszystkie linki z target="_blank" miały jawnie ustawione rel="noopener noreferrer".
Oto dlaczego mimo „automatyki” warto wciąż dodawać rel="noopener":
- dla starszych przeglądarek, które nie mają domyślnego zabezpieczenia,
- dla czytelności kodu – zespół i audytorzy widzą wprost intencję zabezpieczenia linku,
- wiele skanerów bezpieczeństwa i wytycznych (np. CWE, OWASP) nadal traktuje brak
noopenerprzytarget="_blank"jako problem lub co najmniej „złą praktykę”.
Jak poprawnie stosować rel="noopener" w HTML i JS
HTML – zasada główna
Prosta reguła:
Każdy link z
target="_blank"powinien miećrel="noopener(często razem znoreferrer).
Przykłady:
<!-- Bez ukrywania referera (bez wpływu na analitykę) -->
<a href="https://example.com" target="_blank" rel="noopener">Zewnętrzny artykuł</a>
<!-- Z ukryciem referera (dodatkowa warstwa prywatności) -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">Strona partnera</a>
JavaScript – otwieranie okien / kart
Jeśli otwierasz nowe karty przez window.open, przekaż słowa kluczowe noopener i noreferrer:
const link = 'https://example.com';
// Bezpieczne otwarcie nowej karty
window.open(link, '_blank', 'noopener,noreferrer');
Alternatywnie – zgodnie z zaleceniami CWE – możesz ręcznie wyzerować opener:
const newWindow = window.open(link, '_blank');
if (newWindow) {
newWindow.opener = null; // odcięcie dostępu do rodzica
}
Jak testować podatność na reverse tabnabbing
Zgodnie z wytycznymi OWASP Web Security Testing Guide wykonaj następujące kroki:
- przejrzyj kod HTML aplikacji,
- wyszukaj wszystkie linki
<a>ztarget="_blank", - sprawdź, czy mają ustawiony
relz wartościaminoopenerinoreferrer.
Jeżeli link ma target="_blank", ale brak rel="noopener", aplikacja prawdopodobnie jest podatna na reverse tabnabbing (przynajmniej w starszych przeglądarkach).
W narzędziach automatycznych (lintery, skanery bezpieczeństwa, audyty dostępności/SEO) często istnieją gotowe reguły wykrywające target="_blank" bez rel="noopener".
Wpływ noopener i noreferrer na SEO i analitykę
noopener a SEO
Atrybut rel="noopener" nie wpływa bezpośrednio na SEO – nie mówi wyszukiwarce, jak ma traktować link (w przeciwieństwie do nofollow), a jego celem jest zwiększenie bezpieczeństwa przez blokadę dostępu do window.opener. Z perspektywy SEO to atrybut neutralny – możesz i powinieneś spokojnie go używać.
noreferrer a źródła ruchu
Atrybut rel="noreferrer" zapobiega przekazaniu informacji o stronie odsyłającej (brak nagłówka Referer), więc strona docelowa nie zobaczy w statystykach (np. w Google Analytics), że ruch przyszedł z Twojej domeny – będzie traktowany jako „direct” lub nieokreślony.
Z punktu widzenia SEO link nadal jest linkiem i może być indeksowany, natomiast strona docelowa nie zobaczy w analityce źródła ruchu, co może utrudniać raportowanie i analizę kampanii. Z perspektywy analityki, jeśli chcesz przekazywać informację o źródle partnerom lub zespołom analitycznym, rozważ stosowanie wyłącznie rel="noopener", bez noreferrer.
Główne zadanie noopener i noreferrer to bezpieczeństwo i stabilność, a nie bezpośrednie sterowanie rankingiem w wyszukiwarce.
Związek z dostępnością (a11y) – nie tylko bezpieczeństwo
-
Bezpieczeństwo użytkownika to element dostępności. Strona, którą łatwo wykorzystać jako wektor phishingu, w praktyce obniża dostępność – szczególnie dla osób mniej technicznych. Zastosowanie
rel="noopener"zmniejsza to ryzyko. -
Ostrożne używanie
target="_blank". Z punktu widzenia dostępności (WCAG, UX) otwieranie linków w nowej karcie powinno być używane oszczędnie i wyraźnie komunikowane użytkownikowi. Osoby korzystające z czytników ekranu, klawiatury czy technologii wspomagających mogą mieć trudności z orientacją, gdy niespodziewanie otwiera się nowa karta. -
Kompromis. Gdy musisz użyć
target="_blank"(np. dokumenty, zasoby zewnętrzne), zastosujrel="noopener"i poinformuj użytkownika w treści linku lub w atrybuciearia-label, że link otworzy się w nowej karcie.
Dobre praktyki – checklista dla front-endu i devów
Przy projektowaniu i implementacji linków:
- Zasada podstawowa – dla każdego
target="_blank"dodawaj co najmniejrel="noopener"; - Gdy chcesz ukryć źródło ruchu – stosuj
rel="noopener noreferrer", mając świadomość wpływu na analitykę i statystyki refererów; - JavaScript – przy
window.openużywaj parametrów"noopener,noreferrer"lub ręcznie ustawiajnewWindow.opener = null; - Audyty i code review – dodaj regułę w linterze/CI, która blokuje mergowanie kodu z
target="_blank"bezrel="noopener"; - Dostępność – używaj
target="_blank"tylko tam, gdzie ma to realny sens, informuj użytkownika, że link otworzy się w nowej karcie, a dla bezpieczeństwa zawsze dodawajrel="noopener"; - Edukacja zespołu – włącz temat reverse tabnabbing do checklist bezpieczeństwa front-endu, wyjaśnij różnice między
noopener,noreferreri innymi wartościamirel(np.nofollow).
Stosowanie rel="noopener" to jedna z najprostszych zmian, które realnie podnoszą bezpieczeństwo użytkowników – bez wpływu na funkcjonalność i SEO; w nowoczesnym ekosystemie webowym to de facto standard dobrych praktyk przy każdym linku otwierającym się w nowej karcie.






