Pytanie Dlaczego Google wstaje, gdy (1); do ich odpowiedzi JSON?


Dlaczego Google się przedkłada while(1); do ich (prywatnych) odpowiedzi JSON?

Oto przykład odpowiedzi podczas włączania i wyłączania kalendarza kalendarz Google:

while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],
  ['remindOnRespondedEventsOnly','true'],
  ['hideInvitations_remindOnRespondedEventsOnly','false_true'],
  ['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]

Zakładam, że to powstrzymuje ludzi od robienia czegoś eval() na tym, ale wszystko, co naprawdę musisz zrobić, to zastąpić while i wtedy będziesz gotowy. Zakładam, że zapobieganie eval polega na tym, że ludzie piszą bezpieczny kod parsujący JSON.

Widziałem to również w kilku innych miejscach, ale o wiele więcej dzięki Google (poczta, kalendarz, kontakty itp.). Dziwnie, Dokumenty Google zaczynać z &&&START&&& zamiast tego wydaje się zacząć od Kontaktów Google while(1); &&&START&&&.

Co tu się dzieje?


3491
2018-04-19 18:00


pochodzenie


Uważam, że twoje pierwsze wrażenie jest poprawne. Jeśli zaczniesz szukać kodu i spróbujesz przyciąć strumień wejściowy w zależności od źródła, zrewiduj go i zrób to w bezpieczny sposób (a także dzięki działaniom Google, łatwiej). - Esteban Küber
prawdopodobnie kolejne pytanie: Dlaczego google prepend )]}' teraz zamiast while(1);? Czy odpowiedzi byłyby takie same? - Gizmo
Zapobiegłoby eval, ale nie w nieskończonej pętli. - Mardoxx
To )]}' może być również zapisywanie bajtów, takich jak Facebook for(;;); który zapisuje jeden bajt :) - Gras Double
W celu zapobieżenia ujawnieniu json, tj. JSON hijacking - Ashraf.Shk786


Odpowiedzi:


Zapobiega Porwanie JSON.

Zmyślny przykład: powiedzmy, że Google ma adres URL mail.google.com/json?action=inbox która zwraca pierwsze 50 wiadomości ze skrzynki odbiorczej w formacie JSON. Złe witryny w innych domenach nie mogą wysyłać żądań AJAX, aby uzyskać te dane z powodu zasad tego samego pochodzenia, ale mogą zawierać adres URL za pośrednictwem <script> etykietka. Adres URL odwiedzono za pomocą Twój ciasteczka i przez nadpisywanie globalnego konstruktora tablic lub metod uzyskiwania dostępu mogą mieć metodę wywoływaną za każdym razem, gdy ustawiony jest atrybut object (tablica lub hash), co pozwala im odczytać zawartość JSON.

The while(1); lub &&&BLAH&&& zapobiega temu: żądanie AJAX na mail.google.com będzie miał pełny dostęp do zawartości tekstowej i może ją usunąć. Ale a <script> wstawianie tagów ślepo wykonuje JavaScript bez żadnego przetwarzania, co skutkuje nieskończoną pętlą lub błędem składni.

To nie rozwiązuje problemu fałszywe zapytanie o witrynę.


3770
2018-04-19 18:11



Dlaczego prośba o uzyskanie tych danych nie wymaga użycia tokena CSRF? - Jakub P.
Robi for(;;); wykonać tę samą pracę? Widziałem to w odpowiedziach na Facebooka z Facebooka. - King Julien
@JakubP. Przechowywanie i utrzymywanie tokenów CSRF w skali Google wymaga dużej ilości infrastruktury i kosztów. - abraham
@JakubP. Token anty-CSRF bałagan z buforowaniem i wymaga pewnej ilości kryptograficznej oceny serwera. W skali Google wymagałoby to dużo procesora. Ten rodzaj obciąża go klientowi. - bluesmoon
Wydaje mi się, że lepszym sposobem byłoby pozwolić serwerowi wysłać tylko JSON, jeśli został ustawiony poprawny nagłówek. Możesz to zrobić w wywołaniu AJAX, ale nie za pomocą znaczników skryptów. W ten sposób wrażliwe informacje nigdy nie zostaną wysłane, a Ty nie musisz polegać na zabezpieczeniach po stronie przeglądarki. - mcv


Zapobiega ujawnieniu odpowiedzi poprzez porwanie JSON.

Teoretycznie treść odpowiedzi HTTP jest chroniona przez zasady Same Origin: strony z jednej domeny nie mogą uzyskać żadnych informacji ze stron w innej domenie (chyba że jest to wyraźnie dozwolone).

Osoba atakująca może żądać stron w innych domenach w Twoim imieniu, np. za pomocą a <script src=...> lub <img>tag, ale nie może uzyskać żadnych informacji o wyniku (nagłówki, zawartość).

Tak więc, jeśli odwiedzasz stronę atakującego, nie może odczytać Twojego adresu e-mail z gmail.com.

Poza tym, że przy użyciu znacznika skryptu do żądania treści JSON, JSON jest wykonywany jako JavaScript w kontrolowanym środowisku atakującego. Jeśli atakujący może zastąpić konstruktor Array lub Object lub inną metodę użytą podczas konstruowania obiektu, wszystko w JSON przejdzie przez kod napastnika i zostanie ujawnione.

Zauważ, że dzieje się to w momencie, gdy JSON jest wykonywany jako JavaScript, a nie w czasie jego analizy.

Istnieje wiele środków zaradczych:

Upewniając się, że JSON nigdy nie zostanie wykonany

Umieszczając while(1); oświadczenie przed danymi JSON, Google upewnia się, że dane JSON nigdy nie są wykonywane jako Javascript.

Tylko prawidłowa strona może pobrać całą zawartość, usunąć ją while(1);i parsować resztę jako JSON.

Rzeczy jak for(;;); na przykład na Facebooku pojawiły się te same wyniki.

Upewnienie się, że JSON nie jest poprawnym JavaScriptem

Podobnie, dodawanie nieprawidłowych tokenów przed JSON, np &&&START&&&, upewnia się, że nigdy nie zostanie wykonany.

Zawsze zwracaj JSON z Obiektem na zewnątrz

To jest OWASP zalecany sposób aby chronić się przed porwanieniem JSON i jest mniej inwazyjny.

Podobnie jak poprzednie pomiary, zapewnia, że ​​JSON nigdy nie zostanie wykonany jako JavaScript.

Prawidłowy obiekt JSON, jeśli nie jest w nim nic, nie jest poprawny w JavaScript:

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

Jest to jednak poprawne JSON:

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

Tak więc, upewnienie się, że zawsze zwracasz obiekt na najwyższym poziomie odpowiedzi, upewnia się, że JSON nie jest poprawnym JavaScriptem, a jednocześnie jest prawidłowym JSON.

Jak zauważył @hvd w komentarzach, pusty obiekt {} jest poprawnym skryptem JavaScript, a znajomość obiektu jest pusta sama w sobie może być wartościową informacją.

Porównanie powyższych metod

Sposób OWASP jest mniej inwazyjny, ponieważ nie wymaga zmian w bibliotece klienta i przesyła prawidłowy JSON. Nie jest jednak pewne, czy poprzednie lub przyszłe błędy przeglądarki mogą je pokonać. Jak zauważyła @oriadam, nie jest jasne, czy dane mogą zostać ujawnione w wyniku błędu w analizie błędu (np. Window.onerror).

Sposób Google wymaga biblioteki klienta, aby umożliwić automatyczną de-serializację i może być uważana za bezpieczniejszą w odniesieniu do błędów przeglądarki.

Obie metody wymagają zmian po stronie serwera w celu uniknięcia przypadkowego wysłania przez programistę zagrożonego JSON.


445
2018-02-02 12:09



Rekomendacja OWASP jest interesująca ze względu na swoją prostotę. Ktoś wie, dlaczego droga Google jest bezpieczniejsza? - funroll
wierzę w to nie jest bardziej bezpieczny w żaden sposób. Zapewnienie OWASP tutaj wydaje się wystarczającym powodem dla +1. - vaxquis
Jakie przeglądarki w 2014 roku umożliwiają zastąpienie konstruktora Array lub Object? - Filipe Giusti
Warto zauważyć czemu zwracanie literału obiektu kończy się niepowodzeniem script tag lub eval funkcjonować. Szelki {} można interpretować jako blok kodu lub literał obiektu, a sam JavaScript preferuje ten pierwszy. Jako blok kodu jest on oczywiście nieważny. Zgodnie z tą logiką nie widzę żadnych przewidywalnych zmian w zachowaniu przeglądarki w przyszłości. - Manngo
Zły kod nie jest wystarczający, ponieważ atakujący może również przejąć kontrolę nad błędem skryptu przeglądarki (window.onerror) Nie jestem pewien, jakie jest zachowanie onerror z błędami składni. Sądzę, że Google też nie był pewien. - oriadam


Ma to na celu zagwarantowanie, że inna strona nie będzie w stanie wykonać nieprzyjemnych sztuczek, aby spróbować ukraść Twoje dane. Na przykład: zastępowanie konstruktora tablicowego, a następnie ten adres URL JSON za pośrednictwem <script> tag, złośliwa strona firmy zewnętrznej może wykraść dane z odpowiedzi JSON. Umieszczając while(1); na początku skrypt zawiesi się.

Z drugiej strony żądanie tej samej witryny, używając XHR i osobnego parsera JSON, może z łatwością zignorować while(1); prefiks.


344
2018-05-16 02:08



Z technicznego punktu widzenia "normalny" analizator składni JSON powinien podać błąd, jeśli masz prefiks. - Matthew Crumley
Atakujący użyliby zwykłego starego <script> element, a nie XHR. - Laurence Gonsalves
@Matthew, oczywiście, ale możesz go usunąć przed przekazaniem danych do parsera JSON. Nie możesz tego zrobić za pomocą a <script> etykietka - bdonlan
Czy są jakieś przykłady tego? Zastępuje się konstruktor tablicowy, ale naprawiono błąd. Nie rozumiem, w jaki sposób można uzyskać dostęp do danych otrzymanych za pośrednictwem znacznika skryptu. Bardzo bym chciał zobaczyć sztuczną implementację, która działa w najnowszej przeglądarce. - Dennis G
@joeltine, nie, nie jest. Widzieć stackoverflow.com/questions/16289894/... .


Oznaczałoby to utrudnienie stronie trzeciej wstawienia odpowiedzi JSON do dokumentu HTML z rozszerzeniem <script> etykietka. Pamiętaj, że <script> tag jest zwolniony z Te same zasady dotyczące pochodzenia.


98
2018-04-19 18:04



To tylko połowa odpowiedzi. Gdyby nie to, żeby przesłonić Object i Arraykonstruktorzy, wykonując prawidłową odpowiedź JSON tak, jakby był JavaScript, byłyby całkowicie nieszkodliwe we wszystkich okolicznościach. Tak while(1); uniemożliwia wykonanie odpowiedzi jako JavaScript, jeśli jest ona celem atrybutu a <script> tag, ale twoja odpowiedź nie wyjaśnia, dlaczego to konieczne. - Mark Amery
ale w jaki sposób zapobiegnie on elementom iframe - Ravinder Payal
@RavinderPayal <iframe> tagi nie są zwolnione z zasad dotyczących tego samego pochodzenia ... - YoYoYonnY
Znacznik skryptu nigdy nie jest zwolniony z tej samej reguły pochodzenia. Czy możesz mi to wyjaśnić? - Suraj Jain


Zapobiega wykorzystywaniu go jako celu prostego <script> etykietka. (Cóż, to mu nie przeszkadza, ale robi to nieprzyjemnie.) W ten sposób źli ludzie nie mogą po prostu umieścić tego tagu w swojej witrynie i polegać na aktywnej sesji, aby umożliwić pobieranie twoich treści.

edytować - zanotuj komentarz (i inne odpowiedzi). Problem dotyczy podcięcia wbudowanych urządzeń, w szczególności Object i Array konstruktorzy. Te mogą być zmienione w taki sposób, że w przeciwnym razie niewinne JSON, gdy zostanie zinterpretowane, może wywołać kod napastnika.


65
2018-04-19 18:02



To tylko połowa odpowiedzi. Gdyby nie to, żeby przesłonić Object i Arraykonstruktorzy, wykonując prawidłową odpowiedź JSON tak, jakby był JavaScript, byłyby całkowicie nieszkodliwe we wszystkich okolicznościach. Tak while(1); uniemożliwia wykonanie odpowiedzi jako JavaScript, jeśli jest ona celem atrybutu a <script> tag, ale twoja odpowiedź nie wyjaśnia, dlaczego to konieczne. - Mark Amery


Od <script> Tag jest zwolniony z Polityki Same Origin, co jest koniecznością bezpieczeństwa w świecie WWW, natomiast (1) po dodaniu do odpowiedzi JSON zapobiega niewłaściwemu użyciu w <script>etykietka.


3
2017-08-18 04:14