JSONP
JSONP (JSON са поставом) је техника коју користе веб програмери како би превазишли међудоменска ограничења наметнута од стране полисе заједничког порекла прегледача која ограничава приступ ресурсима чије је порекло различито од полазног.
JSON је скраћеница од "JavaScript Object Notation" и представља формат у којем су објекти представљени помоћу парова кључева и вредности.
Принцип рада
Да би видели како ова техника ради, прво размотримо URL захтев који испоручује JSON податаке. JavaScript програм може да затражи овај URL преко XMLHttpRequest, на пример. Претпоставимо да је идентификатор корисник за особу Фоо 1234. Прегледач тражи URL http://server.example.com/Users/1234
прослеђујући идентификатор 1234, а примиће податке (углавном динамички генерисане) слично овоме:
{ "Name": "Foo", "Id": 1234, "Rank": 7 }
Овде, HTML <script>
елемент одређује за src
атрибут URL који враћа JSON:
<script type="application/javascript" src="http://server.example.com/Users/1234"> </script>
Прегедач ће, редом, преузети script
датотеку, проценити њен садржај, интерпретирати сирове JSON податке као block и избацити синтаксну грешку. Чак и да су подаци третирани као JavaScript објекат, не би им се могло приступити у JavaScript коду који прегледач извршава, без претходне доделе ове вредности некој променљивој.
У употреби JSONP , URL захтев указује src
на атрибут у <script>
део и враћа JSON податак, заокружен JavaScript кодом (углавном преко позива функције). Овај "wrapped payload" је интерпретиран од стране прегледача. Тако, функција, која је већ дефинисана у JavaScript окружењу, може да манипулише JSON подацима. Типични JSONP захтев и одговор приказан је доле.
Функцијски позив myResponseFunction() је "P" из JSONP— "padding" око чистог JSON-а, или према неким[1] "префикс".
Имајте на уму да за рад са JSONP, сервер мора да врати одговор који садржи JSONP функцију. JSONP не ради са JSON-форматираним резултатом. JSONP функција "тражи" да буде враћена, док "payload", који је примила функција, мора бити договорен од стране клијента и сервера.
По конвенцији, прегледач даје име (позив) функције, према називу вредности параметара упита, углавном користећи назив jsonp
или callback
упита - у захтеву сервера, на пример,
<script type="application/javascript" src="http://server.example.com/Users/1234?callback=parseResponse"> </script>
У овом примеру, примљени "payload" би био:
parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
Убацивање скрипт елемената
JSONP има смисла само када се користи са скрипт елементима. За сваки нови JSONP захтев, прегледач мора да дода нови <script>
елемент, или да искористи неки постојећи. Бивша опција—додавање новог скрипт елемента—је урађена преко DOM манипулације, и позната је као убацивање скрипт елемента. <script>
елемент је убачен у HTML DOM, са URL од жељене JSONP крајње тачке постављене као "src" атрибут. Ово динамичко убацивање скрипт елемента углавом је урађено JavaScript помоћном библиотеком. jQuery и остали frameworks имају JSONP помоћне функције; постоје и самосталне опције.[2][3][4]
Пример динамичког убацивања скрипт елемента за JSONP позив изгледа овако:
<script type="application/javascript" src="http://server.example.com/Users/1234?callback=parseResponse"> </script>
Након што је елемент убачен, прегледач процењује елемент и обавља HTTP GET на URL, преузимајући садржај. Прегледач, потом, процењује враћени "payload" као JavaScript. Ово је типично позивање функције.
На тај начин, употреба JSONP може да дозволи страници прегледача да ради "same-origin policy" преко убацивања скрипт елемента.
Скрипта ради у оквиру укључене странице и, као таква, и даље је предмет cross-domain ограничења у односу на домен странице. То значи да веб страница не може, рецимо, да учита библиотеку која се налази на другом сајту са JSONP и потом дa направи XMLHttpRequest захтев за тај сајт (осим ако је cross-origin дељења ресурса подржан), мада се могу користити и такве библиотеке за прављење XMLHttpRequests на сопственом сајту.
Захтеви cross домена који користе прокси сервер
JavaScript полиса заједничког порекла нормално спречава претраживач да шаље AJAX захтеве различитим доменима и примање одговора (новији претраживачи, који подржавају CORS, могу опустити ово ограничење). Кооперативни прокси сервер, међутим, нема таква ограничења и може пренети захтев прегледача серверу у одвојеном домену , складиштити резултат, и онда вратити JSON payload, када прегледач прави следећи захтев. Сервер ће бити упућен у склопу првог захтева да складишти излаз (POST враћа JSON payload) привремено у локалном снабдевачу (на пример кеширана меморија или у оквиру сесије променљиве), а други захтев прегледача донеће кеширани одговор на почетни упит.[5] The xd_arbiter.php коришћен од стране Facebook's JS SDK је популаран пример технике сарађивања сервера.[6]
Проблеми безбедности
Непоузданост кода
Укључујући скрипт ознаке, главном серверу омогућава се убацивање и прикупљање података на/са веб сајта. Уколико су удаљени сервери рањиви, који омогућавају убацивање Javascript-a, страна коју услужује оригинални сервер је изложена опасности. Ако "нападач" може да спроведе било какав JavaScript код у оригинални веб сајт, онда овај код може да добије додатни JavaScript из било ког домена.[7] У садржај безбедносне политике HTTP хедер дозвољава веб сајтовима да "кажу" веб прегледачима које скрипте могу бити укључене.
Напор је направљен око 2011.г. утврђивањем сигурније и ригоризније дефиниције за JSON[8] , па прегледачи имају прилику укључивања скрипте на основу MIME типа "апликација/json-p". Ако одговор не прође као строги јсон-p, претраживач може да "изда грешку" или једноставно игнорише цео одговор. Међутим, овај приступ је одбијен од стране CORS-a, и прави MIME за jsonp остаје апликација/Јавасцрипт
.[9]
Манипулација позива и рефлективно преузимање података
Непотврђена повратна имена могу да се искористе при преносу марвелозних података клијентима заобилазећи ограничења у вези са апп/јсон
садршајем, као што је и демонстрирано у нападу помоћу рефлективног преузимања података 2014. године.[10]
Фалсификовање захтева
Наивни развој JSONP се заснива на нападима проузрокованим фалсификовању захтева (CSRF или XSRF).[11] јер HTML <скрипт>
ознака не поштују исту политику у реализацији веб прегледача, марвелозне стране могу преузети податке које припадају другим сајтовима користећи JSON. Сајт ће омогућити подацима који су енкодирани помоћу JSON-а да буду процењени у контексту марвелозне стране, могућег откривања шифре или других осетљивих података, под условом да је корисник улогован на неки други сајт.
Ово је проблематично, само ако, подаци енкодирани помоћу JSON-а, садрже осетљиве информације које не би требало да буду лако доступне. Сервер зависи од прегледача који може блокирати податке који немају право приступа. Ова зависност приватности од прегледача може се заобићи тако што сервер одлучује о приватности. Када је захтев прихваћен, онда, може само поставити податке на "жицу". Ексклузивна употреба колачића за одређивање да ли је захтев прихваћен требало би да буде избегнута. Као да је захтев фалсификован.
Rosetta Flash
Rosetta Flash је експлотациона техника која омогућава нападачу да користити сервер са рањивим JSONP крајњим тачкама (изазвана од стране Adobe Flash Player) да увери нападача да је његов аплет настао на рањивом серверу. Апплет може затим послати податке назад до нападача. Exploit користи ActionScript компајлиран у SVF фајл који је сачињен у потпуности од алфа-нумеричких карактера, правећи zlib стрим са одређеним хедером и DEFLATE блоковима са хофмановим кодирањем. Добијени алфанумерички SVF-фајл, који, затим, користи позив параметара JSONP. Велики сајтови, попут Google, Youtube, Facebook, Yahoo!, Yandex, Linkedin, eBay, Instagram i Tumblr били су рањиви до јула 2014. године.[12] Ова рањивост откривена је и објављена од стране компаније Google, а открио је безбедносни инжењер Michele Spagnuolo[13]. Рањивости имају CVE 2014-4671[14] и CVE 2014-5333.[15] Adobe Flash Player верзија 14.0.0.145, објављена 8. јула 2014. године, уведена је строжа провера датотека Flash фајлова,[16] а у верзији 14.0.0.176, објављеној 12. августа 2014. године, трајно су решили проблем,[17] спречавањем рада exploit-a.
Историја
У јулу 2005. године Џорџ Јемпти предложио опциону доделу променљивих у JSON-у.[18][19] Оригинални предлог за JSONP, где је пуњење позив функције, предложио је Боб Ипполито у децембру 2005. године,[20] и сада је користе многе веб 2.0 апликације, као што су дојо алат, Google веб-алат и веб-услуга.
Види још
- Заједничко коришћење ресурса (ЗКР)
- Методе за размену порука
Референце
- ^ „Experimental RDF result set to JSON translator”. Архивирано из оригинала 15. 11. 2014. г. Приступљено 20. 2. 2012.
- ^ „example jsonp library on pastebin”.
- ^ „Basic JSONP helper (pure JS)”.
- ^ „jQuery's $.getJSON utility”.
- ^ „Архивирана копија”. Архивирано из оригинала 09. 02. 2014. г. Приступљено 15. 05. 2016.
- ^ Kinsey, Sean. „Facebook and Cross domain messaging clarification?”. Stack Exchange, Inc. Приступљено 22. 11. 2013.
- ^ Ben Hayak (17. 10. 2014). „Same Origin Method Execution” (PDF). Приступљено 22. 10. 2014.
- ^ „Safer cross-domain Ajax with JSON-P/JSONP”. JSON-P.org. Архивирано из оригинала 04. 03. 2016. г. Приступљено 30. 10. 2011.
- ^ Grey, Eli (27. 6. 2010). „Is this safe for providing JSONP?”. stackoverflow.com. Приступљено 7. 9. 2012.
- ^ Oren Hafif (2014). „Reflected File Download - A New Web Attack Vector”. TrustWave. Архивирано из оригинала 28. 03. 2015. г. Приступљено 25. 3. 2015.
- ^ Grossman, Jeremiah (27. 1. 2006). „Advanced Web Attack Techniques using GMail”. Приступљено 3. 7. 2009.
- ^ Michele, Spagnuolo. „Abusing JSONP with Rosetta Flash”. Архивирано из оригинала 21. 07. 2014. г. Приступљено 20. 7. 2014.
- ^ „Google - list of software vulnerabilities discovered or fixed by Googlers”. Приступљено 29. 7. 2014.
- ^ „MITRE: CVE-2014-4671”. Архивирано из оригинала 23. 09. 2015. г. Приступљено 29. 7. 2014.
- ^ „MITRE: CVE-2014-5333”. Архивирано из оригинала 23. 09. 2015. г. Приступљено 21. 8. 2014.
- ^ „Adobe Security Bulletin APSB14-17”. Приступљено 29. 7. 2014.
- ^ „Adobe Security Bulletin APSB14-18”. Приступљено 21. 8. 2014.
- ^ „eval'ing JSON”. 19. 7. 2005. Архивирано из оригинала 12. 02. 2006. г. Приступљено 15. 05. 2016.
- ^ „json: Message: Re: Comments”. 17. 8. 2005. Архивирано из оригинала 22. 07. 2012. г. Приступљено 15. 05. 2016.
- ^ „Remote JSON - JSONP”. from __future__ import *. Bob.pythonmac.org. 5. 12. 2005. Архивирано из оригинала 08. 06. 2012. г. Приступљено 8. 9. 2008.