JSONP
JSONP lub JSON-P (JSON with Padding) to historyczna technika JavaScript służąca do żądania danych przez ładowanie elementu <script>
, który jest elementem przeznaczonym do ładowania zwykłego JavaScript. Został zaproponowany przez Boba Ippolito w 2005 roku. JSONP umożliwia udostępnianie danych z pominięciem polityki tego samego pochodzenia, która uniemożliwia uruchomienie kodu JavaScript w celu odczytania elementów DOM mediów lub danych XMLHttpRequest pobranych spoza witryny źródłowej strony. Witryna źródłowa jest wskazywana przez kombinację schematu URI, nazwy hosta i numeru portu.
JSONP jest podatny na to, że źródło danych zastępuje nieszkodliwe wywołanie funkcji złośliwym kodem, dlatego w nowoczesnych aplikacjach został wyparty przez udostępnianie zasobów między źródłami (dostępne od 2009 r.).
Funkcjonalność
HTML <script>
jest generalnie dozwolony do wykonywania kodu JavaScript pobranego z obcych źródeł. Usługi odpowiadające czystymi JSON nie były jednak w stanie udostępniać danych z obcych źródeł przed przyjęciem CORS ( udostępnianie zasobów między źródłami ).
Na przykład żądanie skierowane do zagranicznego serwisu http://server.example.com/Users/1234
może zwrócić rekord osoby o imieniu Clem w formacie JSON. Składnia JSON jest zgodna ze składnią obiektów JavaScript.
{ "Imię" : "Clem" , "Id" : 1234 , "Ranga" : 7 }
Bez obsługi mechanizmu CORS próba użycia danych w różnych domenach kończy się błędem JavaScript.
< script type = "application/javascript" src = "http://server.example.com/Users/1234" > </ script >
Przeglądarka pobierze plik <script>
, oceni jego zawartość, błędnie zinterpretuje surowe dane JSON jako blok i zgłosi błąd składni. Nawet jeśli dane zostały zinterpretowane jako literały obiektowe JavaScript, JavaScript działający w przeglądarce nie mógłby uzyskać do nich dostępu, ponieważ bez przypisania zmiennych literały obiektowe są niedostępne.
We wzorcu użycia JSONP żądanie adresu URL wskazywane przez atrybut src
w elemencie <script>
zwraca dane JSON z kodem JavaScript (zwykle wywołaniem funkcji) zawiniętym wokół niego. Ten „zapakowany ładunek” jest następnie interpretowany przez przeglądarkę. W ten sposób funkcja, która jest już zdefiniowana w środowisku JavaScript, może manipulować danymi JSON. Poniżej przedstawiono typowe żądanie JSONP i odpowiedź.
Wywołanie funkcji parseResponse() to „P” JSONP — „dopełnienie” lub „prefiks” wokół czystego JSON. Aby JSONP działał, serwer musi odpowiedzieć odpowiedzią zawierającą funkcję JSONP. JSONP nie działa z wynikami w formacie JSON. Wywołanie funkcji JSONP, które zostanie odesłane, oraz ładunek odbierany przez funkcję muszą zostać uzgodnione przez klienta i serwer. Zgodnie z konwencją serwer dostarczający dane JSON oferuje żądającej stronie internetowej nazwanie funkcji JSONP, zwykle używając nazwy jsonp lub wywołania zwrotnego jako nazwanego parametru ciągu zapytania, w swoim żądaniu do serwera: <script src="http://server.example.com/Users/1234?callback=parseResponse"></script>
.
W tym przykładzie odebrany ładunek wyglądałby następująco:
parseResponse ({ "Nazwa" : "Clem" , "Id" : 1234 , "Ranga" : 7 });
Wstrzyknięcie elementu skryptu
JSONP ma sens tylko wtedy, gdy jest używany z elementem skryptu. Dla każdego nowego żądania JSONP przeglądarka musi dodać nowy <script>
lub ponownie wykorzystać istniejący. Pierwsza opcja — dodanie nowego elementu skryptu — odbywa się poprzez dynamiczną manipulację DOM i jest znana jako wstrzykiwanie elementu skryptu . Element <script>
jest wstrzykiwany do HTML DOM, z adresem URL żądanego punktu końcowego JSONP ustawionym jako atrybut „src”. To dynamiczne wstrzyknięcie elementu skryptu jest zwykle wykonywane przez bibliotekę pomocniczą JavaScript. jQuery a inne frameworki mają funkcje pomocnicze JSONP; istnieją również samodzielne opcje.
Przykład użycia jQuery do dynamicznego wstrzykiwania elementu skryptu dla wywołania JSONP wygląda następująco:
$ . getScript ( "http://server.example.com/Users/192.168.73.96?callback=parseResponse" );
Po wstrzyknięciu elementu przeglądarka ocenia element i wykonuje HTTP GET na src URL, pobierając zawartość. Następnie przeglądarka ocenia zwrotny ładunek jako JavaScript. Jest to zwykle wywołanie funkcji. W ten sposób użycie JSONP może umożliwić stronom przeglądarki obejście zasady tego samego pochodzenia poprzez wstrzyknięcie elementu skryptu.
Skrypt działa w zakresie strony dołączającej i jako taki nadal podlega ograniczeniom między domenami w odniesieniu do domeny strony dołączającej. Oznacza to, że strona internetowa nie może na przykład załadować biblioteki hostowanej w innej witrynie za pośrednictwem JSONP, a następnie wysyłać żądania XMLHttpRequest do tej witryny (chyba że udostępnianie zasobów między źródłami (CORS)), chociaż można użyć takiej biblioteki do zrobić XMLHttpRequests do własnej strony.
Względy bezpieczeństwa
Niewiarygodny kod strony trzeciej
Włączenie elementów skryptu ze zdalnych serwerów umożliwia zdalnym serwerom wstrzykiwanie dowolnej zawartości do witryny internetowej. Jeśli zdalne serwery mają luki, które umożliwiają wstrzykiwanie kodu JavaScript, strona obsługiwana z oryginalnego serwera jest narażona na zwiększone ryzyko. Jeśli osoba atakująca może wstrzyknąć dowolny kod JavaScript do oryginalnej strony internetowej, kod ten może pobrać dodatkowy kod JavaScript z dowolnej domeny, omijając zasady tego samego pochodzenia . Nagłówek HTTP zasad bezpieczeństwa treści pozwala witrynom internetowym informować przeglądarki internetowe, z których skryptów domen mogą być dołączane.
Około 2011 roku podjęto wysiłki w celu zdefiniowania bezpieczniejszej, ścisłej definicji podzbioru dla JSONP, którą przeglądarki mogłyby wymusić na żądaniach skryptów z określonym typem MIME , takim jak „application/json-p”. Jeśli odpowiedź nie została przeanalizowana jako ścisły JSONP, przeglądarka może zgłosić błąd lub po prostu zignorować całą odpowiedź. Jednak to podejście zostało porzucone na rzecz CORS , a poprawnym typem MIME dla JSONP pozostaje application/javascript
.
Różnice w białych znakach
JSONP miał te same problemy, co rozwiązywanie JSON za pomocą eval()
: oba interpretują tekst JSON jako JavaScript, co oznaczało różnice w obsłudze U+2028 ( Separator linii ) i U+2029 ( Separator akapitu ) z właściwego JSON. To sprawiło, że niektóre ciągi JSON stały się niezgodne z prawem w JSONP; serwery obsługujące JSONP musiały zmienić znaczenie tych znaków przed transmisją. Ten problem został naprawiony w ES2019.
Manipulowanie nazwą wywołania zwrotnego i atak z odbitym pobieraniem plików
Nieoczyszczone nazwy wywołań zwrotnych mogą być używane do przekazywania złośliwych danych do klientów, z pominięciem ograniczeń związanych z typem zawartości aplikacji/json
, jak wykazano w ataku z pobieraniem plików (RFD) z 2014 r.
Niezabezpieczone punkty końcowe JSONP mogą również zostać zainfekowane złośliwymi danymi.
Fałszowanie żądań między witrynami
Naiwne wdrożenia JSONP podlegają atakom typu cross-site request forgery (CSRF lub XSRF). Ponieważ element HTML <script>
nie respektuje zasad tego samego pochodzenia w implementacjach przeglądarek internetowych, złośliwa strona może zażądać i uzyskać dane JSON należące do innej witryny. Umożliwi to ocenę danych zakodowanych w formacie JSON w kontekście złośliwej strony, co może skutkować ujawnieniem haseł lub innych poufnych danych, jeśli użytkownik jest aktualnie zalogowany na innej stronie.
Błysk z Rosetty
Rosetta Flash to technika wykorzystywania, która umożliwia atakującemu wykorzystanie serwerów z podatnym na ataki punktem końcowym JSONP, powodując, że program Adobe Flash Player uwierzy, że określony przez atakującego aplet Flash pochodzi z podatnego serwera. Flash Player implementuje zasady tego samego pochodzenia umożliwienie składania zapytań (za pomocą plików cookie) i otrzymywania odpowiedzi z witryny hostingowej. Aplet może następnie wysłać pobrane dane z powrotem do atakującego. Jest to exploit cross-origin, którego skutki są podobne do osadzania dowolnego apletu Flash w podatnej domenie. Exploit wykorzystuje ładunek ActionScript skompilowany do pliku SWF składającego się wyłącznie ze znaków alfanumerycznych poprzez utworzenie strumienia zlib z określonym nagłówkiem i blokami DEFLATE z kodowaniem ad-hoc Huffmana . Wynikowy plik SWF zawierający wyłącznie znaki alfanumeryczne jest następnie używany jako parametr wywołania zwrotnego wywołania JSONP. Znane witryny, takie jak Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram i Tumblr, były podatne na ataki do lipca 2014 r. Luka ta została odkryta i opublikowana przez inżyniera bezpieczeństwa Google Michele Spagnuolo i ma CVE - 2014-4671 i CVE- 2014-5333 . Wersja Adobe Flash Player 14.0.0.145, wydana 8 lipca 2014 r., wprowadziła silniejsze sprawdzanie poprawności plików Flash, a wersja 14.0.0.176, wydana 12 sierpnia 2014 r., sfinalizowała poprawkę uniemożliwiającą działanie tego exploita.
Historia
W lipcu 2005 roku George Jempty zasugerował dodanie opcjonalnego przypisania zmiennej do JSON. Wydaje się, że oryginalna propozycja JSONP, w której wypełnienie jest funkcją wywołania zwrotnego, została złożona przez Boba Ippolito w grudniu 2005 r. i jest obecnie używana przez wiele Web 2.0 , takich jak Dojo Toolkit , Google Web Toolkit i usługi sieciowe .
Zobacz też
Linki zewnętrzne
- filtr po stronie serwera opakowuje każdą odpowiedź w wywołanie zwrotne jsonp – wykonane za pomocą kodu źródłowego jsonp-java
- Potencjalne problemy z bezpieczeństwem związane z formatem JSON
- Źródło danych JSONP dla domen zdalnych