Frame Buster Buster… potrzebny jest kod Buster


422

Załóżmy, że nie chcesz, aby inne witryny „kadrowały” Twoją witrynę w <iframe>:

<iframe src="http://example.org"></iframe>

W ten sposób wstawiasz JavaScript przeciw kadrowaniu i pomijaniu ramek na wszystkich swoich stronach:

/* break us out of any containing iframes */
if (top != self) { top.location.replace(self.location.href); }

Świetny! Teraz automatycznie „kasujesz” lub wyłamujesz się z dowolnego zawierającego iframe. Z wyjątkiem jednego małego problemu.

Jak się okazuje, Twój kod pomijania ramek może zostać pomijany , jak pokazano tutaj :

<script type="text/javascript">
    var prevent_bust = 0  
    window.onbeforeunload = function() { prevent_bust++ }  
    setInterval(function() {  
      if (prevent_bust > 0) {  
        prevent_bust -= 2  
        window.top.location = 'http://example.org/page-which-responds-with-204'  
      }  
    }, 1)  
</script>

Ten kod wykonuje następujące czynności:

  • zwiększa licznik za każdym razem, gdy przeglądarka próbuje opuścić bieżącą stronę za pośrednictwem modułu window.onbeforeunloadobsługi zdarzeń
  • ustawia licznik czasu, który jest uruchamiany co milisekundę setInterval(), a jeśli widzi zwiększenie licznika, zmienia bieżącą lokalizację na serwer kontroli atakującego
  • ten serwer wyświetla stronę z kodem stanu HTTP 204 , co nie powoduje nawigacji w przeglądarce

Moje pytanie brzmi - a to bardziej łamigłówka JavaScript niż faktyczny problem - w jaki sposób możesz pokonać pogromcę klatek?

Miałem kilka myśli, ale nic nie działało w moich testach:

  • próba wyczyszczenia onbeforeunloadzdarzenia przez onbeforeunload = nullnie przyniosła żadnego efektu
  • dodanie alert()zatrzymanego procesu informuje użytkownika, że ​​to się dzieje, ale nie ingeruje w kod w żaden sposób; kliknięcie OK pozwala normalnie kontynuować pomijanie
  • Nie mogę wymyślić żadnego sposobu na wyczyszczenie setInterval()timera

Nie jestem zbytnio programistą JavaScript, więc oto moje wyzwanie: hej, czy możesz zepsuć niszczyciel klatek?


6
Nie jestem pewien, czy frame-buster-buster faktycznie działa ... kiedy próbuję go przetestować (przekierowuję do modułu obsługi, który skonfigurowałem, aby zwrócić 204), uniemożliwia mi nawigację w dowolnym miejscu poza stroną - w tym pisanie w pasku adresu! Muszę zamknąć kartę przeglądarki i otworzyć nową, aby dostać się gdziekolwiek. Innymi słowy, nie jestem pewien, czy to wymaga rozwiązania, ponieważ buster-buster-buster, który chce zostać wyeliminowany, jest ... rozpaczliwy. :) (Albo to, albo spieprzyłem mój test, co nigdy nie mogłoby się zdarzyć ...);)
Matt Winckler

16
Matt, powyższy kod frame-buster-buster zdecydowanie działa. Mój przyjaciel… powiedział mi… o tym. Lub coś. :)
Jeff Atwood

10
Jeff, czy testujesz w obu oknach w tej samej domenie? Wygląda na to, że jesteś, ponieważ gdybyś nie był, ograniczenia bezpieczeństwa uniemożliwiłyby modyfikowanie opcji „onBeforeUnload”
James

29
Na marginesie: Przy publikowaniu przykładów używaj domen takich example.orgjak określono w RFC 2606 ietf.org/rfc/rfc2606.txt
Christoph

3
Odnośnie ogólnego tematu środków zaradczych: galactanet.com/comic/view.php?strip=209
Joey

Odpowiedzi:


149

Nie jestem pewien, czy jest to wykonalne, czy nie - ale jeśli nie możesz złamać ramki, dlaczego po prostu nie wyświetlisz ostrzeżenia. Na przykład jeśli Twoja strona nie jest „górną stroną”, utwórz metodę setInterval, która próbuje złamać ramkę. Jeśli po 3 lub 4 próbach twoja strona wciąż nie jest górną stroną - utwórz element div, który pokrywa całą stronę (pole modalne) z komunikatem i linkiem jak ...

Przeglądasz tę stronę w nieautoryzowanym oknie ramki - (bla bla ... potencjalny problem bezpieczeństwa)

kliknij ten link, aby rozwiązać ten problem

Nie najlepsze, ale nie widzę żadnego sposobu, by mogliby rozwiązać ten problem.


2
Próbowałem tego i to działa. Kolejną rzeczą, którą lubię w tym rozwiązaniu, jest to, że ujawnia użytkownikowi, na jakiej stronie był on / ona przed przejściem do twoich treści. Przykładowy kod: if (parent.frames.length> 0) {top.location.replace (document.location); setTimeout (function () {if (parent.frames.length> 0) {document.location = " google.com ";}}, 10); }
papież

Jest to nie tylko dobry sposób na unikanie nadużyć, ale jest także bardzo przyjazny dla stron, które mogą chcieć iframe z twojej strony, aby rzucić na nią okiem, ale nie zezwalać na korzystanie z niej. Idealnie uważam, że należy użyć zrzutu ekranu strony głównej witryny, z pewnym wyjaśnieniem, dlaczego nie można go użyć w ramce iframe nałożonej na wierzch.
wheresrhys

33
Tak właśnie robi Facebook.
shamittomar

2
ale może to może zostać wykorzystane, jeśli z kolei strona atakująca stworzy fałszywego anty-anty-anty ... (nie wiem, ile anty jesteśmy do tej pory) div lighbox dla siebie prezentując link phishingowy lub cokolwiek ...
tbc

7
Innym pomysłem byłoby po prostu całkowite wymazanie strony czymś w rodzaju document.write("");(po ustaleniu, że jest ona w ramce
gabeio,

211

6
doskonale, obsługując to w przeglądarce .exe to droga bez wątpienia. Kiedy mówisz „większość przeglądarek”, które konkretnie? Nie mogę znaleźć dobrych źródeł dla niczego poza IE8.
Jeff Atwood

2
Oto strona testowa: enhie.com/test/clickjack . Obsługuje Chrome 4.1.249.1042. Obsługa Opery 10.50. Firefox 3.6.2 NIE obsługuje jeszcze. Obsługuje Safari 4.0.3.
EricLaw

1
Firefox 3.6.9 będzie obsługiwał go natywnie ( hackademix.net/2010/08/31/... ) i każda instalacja Firefoksa z NoScript ma go od początku 2009 roku ( hackademix.net/2009/01/29/x-frame- options-in-firefox )
ssokolow

4
Najlepiej połączyć to z Framebuster javascript.
Jesse Weigert

1
Lub połącz to z odpowiedzią z grudnia '12 na tej stronie: stackoverflow.com/a/13708510/328397
goodguys_activate 28.03.2013

34

Zastosowaliśmy następujące podejście w jednej z naszych stron internetowych z http://seclab.stanford.edu/websec/framebusting/framebust.pdf

<style>
 body { 
 display : none   
}
</style>
<script>
if(self == top) {
document.getElementsByTagName("body")[0].style.display = 'block';
}
else{
top.location = self.location;
}
</script>

3
Bingo! Nie jestem pewien, dlaczego nie jest to bardziej uprzywilejowane, ponieważ jest to najlepsza odpowiedź (obok odpowiedzi Opcje X-Frame, ale najlepiej połączyć obie)
Jesse Weigert

1
Tę odpowiedź lub moją należy wybrać :)

Podoba mi się twój pomysł użycia zarówno tego, jak i X-Frame-Options: odmów odpowiedzi.
Max West

Wymaga to JS, co jest dość dużym obciążeniem IMHO.
Navin

1
+1 - To najlepsza odpowiedź, gdy nie można użyć OPCJI RAMY X. (Na przykład, jeśli musisz warunkowo zezwolić lub odmówić w zależności od strony odsyłającej.)
Jay Sullivan,

29

Wyszło na to i wydaje się, że działa przynajmniej w przeglądarce Firefox i przeglądarce Opera.

if(top != self) {
 top.onbeforeunload = function() {};
 top.location.replace(self.location.href);
}

2
zarówno rozwiązanie Jani, jak i Jeffa (po edycji) są poprawne i działają równorzędnie; dając Jani'owi akceptację, ponieważ jego rozwiązanie działało poprawnie bez żadnej edycji
Jeff Atwood

29
Działa to tylko wtedy, gdy dwa okna należą do tej samej domeny; rzadkie zdarzenie, gdy chcesz uciec z ramki.
James

Jeśli zaangażowane są zagnieżdżone ramki, będziesz musiał przejść łańcuch ramek i usunąć wszystkie onbeforeunloadmoduły obsługi, nie tylko te na górze!
Christoph

12
ważne wyjaśnienie: działało to dla mnie, ponieważ element iframe src = był ustawiany dynamicznie, a zatem zasada między domenami NIE obowiązywała. JP ma całkowitą rację, w statycznym src = to nie zadziałałoby.
Jeff Atwood,

5
ok teraz może ktoś wymyślić buster ramki buster buster buster?
Epaga,

23

Biorąc pod uwagę obecny standard HTML5, który wprowadził piaskownicę dla iframe, wszystkie kody pomijania ramek podane na tej stronie można wyłączyć, gdy atakujący używa sandboksa, ponieważ ogranicza to iframe:

allow-forms: Allow form submissions.
allow-popups: Allow opening popup windows.
allow-pointer-lock: Allow access to pointer movement and pointer lock.
allow-same-origin: Allow access to DOM objects when the iframe loaded form same origin
allow-scripts: Allow executing scripts inside iframe
allow-top-navigation: Allow navigation to top level window

Zobacz: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#attr-iframe-sandbox

Rozważmy teraz, że atakujący użył następującego kodu do hostowania witryny w ramce iframe:

<iframe src="URI" sandbox></iframe>

Wtedy cały kod pomijania ramek JavaScript zakończy się niepowodzeniem.

Po sprawdzeniu całego kodu magistrali ramki we wszystkich przypadkach działa tylko ta ochrona:

<style id="antiClickjack">body{display:none !important;}</style>
<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

pierwotnie zaproponowane przez Gustava Rydstedta, Elie Bursztein, Dan Boneh i Collin Jackson (2010)


19

Po zastanowieniu się przez chwilę, wierzę, że to pokaże im, kto jest szefem ...

if(top != self) {
  window.open(location.href, '_top');
}

Użycie _topjako parametru docelowego window.open()spowoduje uruchomienie go w tym samym oknie.


6
if (top != self) {
  top.location.replace(location);
  location.replace("about:blank"); // want me framed? no way!
}

6

Będę odważny i wrzucę czapkę na pierścień na tym (jakkolwiek starożytnym), zobaczę, ile głosów negatywnych mogę zebrać.

Oto moja próba, która wydaje się działać wszędzie, gdzie ją testowałem (Chrome20, IE8 i FF14):

(function() {
    if (top == self) {
        return;
    }

    setInterval(function() {
        top.location.replace(document.location);
        setTimeout(function() {
            var xhr = new XMLHttpRequest();
            xhr.open(
                'get',
                'http://mysite.tld/page-that-takes-a-while-to-load',
                false
            );
            xhr.send(null);
        }, 0);
    }, 1);
}());

Umieściłem ten kod na końcu <head>i nazwałem go od końca, <body>aby upewnić się, że moja strona jest renderowana, zanim zacznie się kłócić ze złośliwym kodem. Nie wiem, czy to najlepsze podejście, YMMV.

Jak to działa?

... słyszę, jak pytasz - szczera odpowiedź brzmi: tak naprawdę nie wiem. Sprawienie, by działało wszędzie, gdzie testowałem, wymagało wiele wysiłku, a dokładny efekt może się nieznacznie różnić w zależności od tego, gdzie go uruchomisz.

Oto sposób myślenia:

  • Ustaw funkcję, aby działała w możliwie najniższym odstępie czasu. Podstawową koncepcją każdego realistycznego rozwiązania, które widziałem, jest wypełnienie harmonogramu większą liczbą zdarzeń niż ma to miejsce w przypadku buster-buster ramki.
  • Za każdym razem, gdy funkcja jest uruchamiana, spróbuj zmienić lokalizację górnej ramki. Dość oczywisty wymóg.
  • Zaplanuj także natychmiastowe uruchamianie funkcji, której ukończenie zajmie dużo czasu (blokując w ten sposób buster-buster-buster przed ingerencją w zmianę lokalizacji). Wybrałem synchroniczny XMLHttpRequest, ponieważ jest to jedyny mechanizm, o którym myślę, że nie wymaga (lub przynajmniej prosi) o interakcję użytkownika i nie żuje czasu procesora użytkownika.

W moim http://mysite.tld/page-that-takes-a-while-to-load(celu XHR) użyłem skryptu PHP, który wygląda następująco:

<?php sleep(5);

Co się dzieje?

  • Chrome i Firefox czekają 5 sekund na zakończenie XHR, a następnie pomyślnie przekierowują na adres URL strony w ramce.
  • IE przekierowuje niemal natychmiast

Czy nie możesz uniknąć czasu oczekiwania w Chrome i Firefox?

Najwyraźniej nie. Na początku wskazałem XHR na adres URL, który zwróciłby 404 - to nie działało w Firefoksie. Następnie wypróbowałem sleep(5);podejście, na którym ostatecznie znalazłem tę odpowiedź, a potem zacząłem bawić się długością snu na różne sposoby. Nie mogłem znaleźć żadnego prawdziwego wzorca tego zachowania, ale zauważyłem, że jeśli jest za krótki, konkretnie Firefox nie będzie grał w piłkę (Chrome i IE wydają się być dość dobrze zachowane). Nie wiem, jaka jest definicja „zbyt krótkiego” w rzeczywistości, ale wydaje się, że za każdym razem działa 5 sekund .


Jeśli któryś przechodzący ninja Javascript chce trochę lepiej wyjaśnić, co się dzieje, dlaczego (prawdopodobnie) jest to zły, niewiarygodny, najgorszy kod, jaki kiedykolwiek widzieli itp. Z przyjemnością wysłucham.


Wydaje się, że możesz usunąć wszystkie swoje niepokojące zdania
mplungjan

6

Począwszy od 2015 r. Powinieneś w tym celu stosować frame-ancestorsdyrektywę CSP2 . Jest to realizowane za pomocą nagłówka odpowiedzi HTTP.

na przykład

Content-Security-Policy: frame-ancestors 'none'

Oczywiście niewiele przeglądarek obsługuje CSP2, dlatego dobrze jest dołączyć stary X-Frame-Optionsnagłówek:

X-Frame-Options: DENY

Radzę jednak uwzględnić oba te elementy, w przeciwnym razie Twoja witryna będzie nadal podatna na ataki Clickjacking w starych przeglądarkach i oczywiście otrzymasz niepożądane obramowanie, nawet bez złośliwych zamiarów. Obecnie większość przeglądarek aktualizuje się automatycznie, jednak użytkownicy korporacyjni nadal utknęli na starych wersjach programu Internet Explorer ze względu na starszą zgodność aplikacji.


1
Wszystkie główne przeglądarki obsługują teraz CSP. To poprawna odpowiedź w 2019 roku i dającej się przewidzieć przyszłości.
Stephen R

5

Ok, więc wiemy, że były w ramce. Więc my location.href do innej specjalnej strony ze ścieżką jako zmienną GET. Wyjaśniamy teraz użytkownikowi, co się dzieje i udostępniamy link z opcją target = "_ TOP". Jest to proste i prawdopodobnie działałoby (nie przetestowałem go), ale wymaga interakcji użytkownika. Może mógłbyś wskazać użytkownikowi szkodliwą witrynę i sprawić, że gdzieś na stronie znajdzie się hałaśliwy jack-jack… Po prostu pomysł, ale to działa noc…


5

Wszystkie proponowane rozwiązania bezpośrednio wymuszają zmianę położenia górnego okna. Co jeśli użytkownik chce, aby ramka tam była? Na przykład górna ramka w wynikach wyszukiwania wyszukiwarek.

Napisałem prototyp, w którym domyślnie wszystkie wejścia (łącza, formularze i elementy wejściowe) są wyłączone i / lub nie robią nic po aktywacji.

Jeśli zostanie wykryta ramka zawierająca, wejścia są wyłączone, a u góry strony wyświetlany jest komunikat ostrzegawczy. Komunikat ostrzegawczy zawiera link, który otworzy bezpieczną wersję strony w nowym oknie. Zapobiega to wykorzystywaniu strony do klikania, a jednocześnie pozwala użytkownikowi przeglądać zawartość w innych sytuacjach.

Jeśli nie zostanie wykryta żadna zawierająca ramka, wejścia są aktywne.

Oto kod. Musisz ustawić standardowe atrybuty HTML na wartości bezpieczne i dodać dodatkowe atrybuty zawierające wartości rzeczywiste. Prawdopodobnie jest niekompletny i dla pełnego bezpieczeństwa dodatkowe atrybuty (myślę o modułach obsługi zdarzeń) prawdopodobnie będą musiały być traktowane w ten sam sposób:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
  <head>
    <title></title>
    <script><!--
      function replaceAttributeValuesWithActualOnes( array, attributeName, actualValueAttributeName, additionalProcessor ) {
        for ( var elementIndex = 0; elementIndex < array.length; elementIndex += 1 ) {
          var element = array[ elementIndex ];
          var actualValue = element.getAttribute( actualValueAttributeName );
          if ( actualValue != null ) {
            element[ attributeName ] = actualValue;
          }

          if ( additionalProcessor != null ) {
            additionalProcessor( element );
          }
        }
      }

      function detectFraming() {
        if ( top != self ) {
          document.getElementById( "framingWarning" ).style.display = "block";
        } else {
          replaceAttributeValuesWithActualOnes( document.links, "href", "acme:href" );

          replaceAttributeValuesWithActualOnes( document.forms, "action", "acme:action", function ( form ) {
            replaceAttributeValuesWithActualOnes( form.elements, "disabled", "acme:disabled" );
          });
        }
      }
      // -->
    </script>
  </head>
  <body onload="detectFraming()">
    <div id="framingWarning" style="display: none; border-style: solid; border-width: 4px; border-color: #F00; padding: 6px; background-color: #FFF; color: #F00;">
      <div>
        <b>SECURITY WARNING</b>: Acme App is displayed inside another page.
        To make sure your data is safe this page has been disabled.<br>
        <a href="framing-detection.html" target="_blank" style="color: #090">Continue working safely in a new tab/window</a>
      </div>
    </div>
    <p>
      Content. <a href="#" acme:href="javascript:window.alert( 'Action performed' );">Do something</a>
    </p>
    <form name="acmeForm" action="#" acme:action="real-action.html">
      <p>Name: <input type="text" name="name" value="" disabled="disabled" acme:disabled=""></p>
      <p><input type="submit" name="save" value="Save" disabled="disabled" acme:disabled=""></p>
    </form>
  </body>
</html>

Problem polega na tym, że twórca ramek może użyć pozycji: absolutnie, aby umieścić aktywny przycisk na nieaktywnych przyciskach, a użytkownik po prostu zobaczy Twoją stronę i pomyśli, że klika TWOJE przyciski.
jmucchiello,

Komunikat ostrzegawczy nadal będzie wyświetlany, ale oczywiście łatwo zasłaniasz link do bezpiecznej strony, jak sugerujesz. Ale po co męczyć się z kadrowaniem mojej strony, aby ludzie kliknęli znajomy przycisk, jeśli można po prostu skopiować stronę i osiągnąć ten sam efekt? Powyższy kod zapobiega przede wszystkim kliknięciom. Jeśli wyświetlasz moją stronę niewidocznie nad inną stroną, nie można wywoływać działań w mojej witrynie.
Johan Stuyts

Jeśli zostanie on umieszczony w ramce strefy ograniczonej IE8 lub ramce piaskownicy Chrome, JavaScript nigdy się nie uruchomi. Zastanawiam się, jakie modyfikacje są potrzebne w tych przypadkach
goodguys_activate

4

Możesz zmienić wartość licznika, ale jest to oczywiście kruche rozwiązanie. Możesz załadować zawartość za pośrednictwem AJAX po ustaleniu, że witryna nie mieści się w ramce - nie jest to również świetne rozwiązanie, ale mam nadzieję, że pozwoli to uniknąć uruchomienia zdarzenia przed załadowaniem (zakładam).

Edycja: Kolejny pomysł. Jeśli wykryjesz, że jesteś w ramce, poproś użytkownika o wyłączenie javascript, zanim klikniesz link prowadzący do pożądanego adresu URL (przekazując kwerendę, która informuje twoją stronę, że może ponownie włączyć javascript, gdy tylko to zrobi) są tam).

Edycja 2: Idź nuklearnie - jeśli wykryjesz, że jesteś w ramce, po prostu usuń treść dokumentu i wydrukuj nieprzyjemną wiadomość.

Edycja 3: Czy możesz wyliczyć górny dokument i ustawić wszystkie funkcje na null (nawet anonimowe)?


Program Outlook (wcześniej Hotmail) „przechodzi w stan nuklearny”, jeśli nie może wydostać się z ramki - umieszcza całą zawartość <body>wewnątrz <plaintext>znacznika ustawionego na display: none. Jest dość skuteczny.
uınbɐɥs

4

Jeśli dodasz alert bezpośrednio po kodzie bustera, alert zablokuje wątek javascript i pozwoli na załadowanie strony. Tak właśnie działa StackOverflow, który wypada z moich ramek iframe, nawet gdy używam funkcji pomijania klatek. Działa również z moją prostą stroną testową. Zostało to przetestowane tylko w Firefoksie 3.5 i IE7 w systemie Windows.

Kod:

<script type="text/javascript">
if (top != self){
  top.location.replace(self.location.href);
  alert("for security reasons bla bla bla");
}
</script>

3

Myślę, że prawie tam byłeś. Czy próbowałeś:

window.parent.onbeforeunload = null;
window.parent.location.replace(self.location.href);

lub alternatywnie:

window.parent.prevent_bust = 0;

Uwaga: Właściwie nie testowałem tego.


1
Zredagowałem twój przykładowy kod (test dla rodzica wydaje się nie udany), ale edytowana wersja NIE działa!
Jeff Atwood,

1
Fajne. Zawsze trudno jest odpowiedzieć za pomocą nieprzetestowanego kodu - robię to, aby przynajmniej przejść przez ten pomysł - i pozwolić debugującemu biednemu pytającemu. :)
Jeff Meatball Yang

12
Nie zadziała, jeśli rodzic jest w innej domenie, co jest prawdopodobne!
Josh Stodola

2

A co z wielokrotnym dzwonieniem do Bustera? Spowoduje to powstanie wyścigu, ale można mieć nadzieję, że buster wyjdzie na wierzch:

(function() {
    if(top !== self) {
        top.location.href = self.location.href;
        setTimeout(arguments.callee, 0);
    }
})();

2

Jeśli spojrzysz na wartości zwracane przez setInterval(), są to zwykle pojedyncze cyfry, więc zwykle możesz wyłączyć wszystkie takie przerwania za pomocą jednego wiersza kodu:

for (var j = 0 ; j < 256 ; ++j) clearInterval(j)


0

setInterval i setTimeout tworzą automatycznie zwiększający się interwał. Za każdym razem, gdy wywoływane jest setTimeout lub setInterval, liczba ta wzrasta o jeden, więc jeśli wywołasz setTimeout, otrzymasz bieżącą, najwyższą wartość.

   var currentInterval = 10000;
   currentInterval += setTimeout( gotoHREF, 100 );
   for( var i = 0; i < currentInterval; i++ ) top.clearInterval( i );
   // Include setTimeout to avoid recursive functions.
   for( i = 0; i < currentInterval; i++ )     top.clearTimeout( i );

   function gotoHREF(){
           top.location.href = "http://your.url.here";
   }

Ponieważ prawie nie zdarza się, że działa 10000 jednoczesnych setIntervals i setTimeout, a ponieważ setTimeout zwraca „ostatni interwał lub limit czasu utworzony + 1”, a ponieważ top.clearInterval jest nadal dostępny, to pokona ataki czarnego kapelusza na ramkę strony internetowe opisane powyżej.


0

Użyj htaccess, aby uniknąć zestawu ramek, ramek iframe i treści takich jak obrazy.

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://www\.yoursite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule ^(.*)$ /copyrights.html [L]

Spowoduje to wyświetlenie strony z prawami autorskimi zamiast oczekiwanej.


Zależy to od strony odsyłającej, która jest a) nie zawsze ustawiona (ze względu na ustawienia przeglądarki lub rozszerzenia lub po prostu dlatego, że strona odsyłająca korzysta z HTTPS bez użycia <meta name="referrer" …/>ib) również ustawiona po kliknięciu linków, więc również nie zezwalasz na linki do swojej strony i łamiesz sieć.
Martin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.