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.onbeforeunload
obsł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
onbeforeunload
zdarzenia przezonbeforeunload = null
nie 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?
javascript
html
iframe
framebusting
Jeff Atwood
źródło
źródło
example.org
jak określono w RFC 2606 ietf.org/rfc/rfc2606.txtOdpowiedzi:
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 ...
Nie najlepsze, ale nie widzę żadnego sposobu, by mogliby rozwiązać ten problem.
źródło
document.write("");
(po ustaleniu, że jest ona w ramceFWIW, większość obecnych przeglądarek obsługują te X-Frame-Options: zaprzeczyć dyrektywę, która działa nawet wtedy, gdy skrypt jest wyłączony.
IE8:
http://blogs.msdn.com/ie/archive/2009/01/27/ie8-security-part-vii-clickjacking-defenses.aspx
Firefox (3.6.9)
https://bugzilla.mozilla.org/show_bug.cgi?id=475530
https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header
Chrome / Webkit
http://blog.chromium.org/2010/01/security-in-depth-new-security-features.html
http://trac.webkit.org/changeset/42333
źródło
Zastosowaliśmy następujące podejście w jednej z naszych stron internetowych z http://seclab.stanford.edu/websec/framebusting/framebust.pdf
źródło
Wyszło na to i wydaje się, że działa przynajmniej w przeglądarce Firefox i przeglądarce Opera.
źródło
onbeforeunload
moduły obsługi, nie tylko te na górze!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:
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:
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:
pierwotnie zaproponowane przez Gustava Rydstedta, Elie Bursztein, Dan Boneh i Collin Jackson (2010)
źródło
Po zastanowieniu się przez chwilę, wierzę, że to pokaże im, kto jest szefem ...
Użycie
_top
jako parametru docelowegowindow.open()
spowoduje uruchomienie go w tym samym oknie.źródło
źródło
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):
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:
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:Co się dzieje?
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.
źródło
Począwszy od 2015 r. Powinieneś w tym celu stosować
frame-ancestors
dyrektywę CSP2 . Jest to realizowane za pomocą nagłówka odpowiedzi HTTP.na przykład
Oczywiście niewiele przeglądarek obsługuje CSP2, dlatego dobrze jest dołączyć stary
X-Frame-Options
nagłówek: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.
źródło
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…
źródło
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:
źródło
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)?
źródło
<body>
wewnątrz<plaintext>
znacznika ustawionego nadisplay: none
. Jest dość skuteczny.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:
źródło
Myślę, że prawie tam byłeś. Czy próbowałeś:
lub alternatywnie:
Uwaga: Właściwie nie testowałem tego.
źródło
A co z wielokrotnym dzwonieniem do Bustera? Spowoduje to powstanie wyścigu, ale można mieć nadzieję, że buster wyjdzie na wierzch:
źródło
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:źródło
Mógłbym właśnie znaleźć sposób, by zniszczyć javascript w kamerze. Korzystając z funkcji getElementsByName w mojej funkcji javascript, utworzyłem pętlę między pomijaniem ramek a rzeczywistym skryptem pomijania ramek. sprawdź ten post. http://www.phcityonweb.com/frame-buster-buster-buster-2426
źródło
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ść.
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.
źródło
Użyj htaccess, aby uniknąć zestawu ramek, ramek iframe i treści takich jak obrazy.
Spowoduje to wyświetlenie strony z prawami autorskimi zamiast oczekiwanej.
źródło
<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ć.