JSONP

JSONP , eller JSON-P (JSON with Padding), är en historisk JavaScript-teknik för att begära data genom att ladda ett <script> -element, vilket är ett element avsett att ladda vanligt JavaScript. Det föreslogs av Bob Ippolito 2005. JSONP möjliggör delning av data som går förbi principen om samma ursprung, vilket inte tillåter körning av JavaScript-kod för att läsa media-DOM-element eller XMLHttpRequest-data hämtade från sidans ursprungswebbplats. Ursprungsplatsen indikeras av en kombination av URI-schema, värdnamn och portnummer.

JSONP är sårbart för att datakällan ersätter det ofarliga funktionsanropet med skadlig kod, vilket är anledningen till att den har ersatts av resursdelning mellan olika ursprung (tillgänglig sedan 2009) i moderna applikationer.

Funktionalitet

HTML -elementet <script> tillåts i allmänhet exekvera JavaScript-kod som hämtats från främmande ursprung. Tjänster som svarade med ren JSON -data kunde dock inte dela data från utländskt ursprung innan CORS ( cross-origin resource sharing) togs i bruk .

Till exempel kan en begäran till en utländsk tjänst http://server.example.com/Users/1234 returnera en post för en person som heter Clem i JSON-formatet. JSON-syntaxen överensstämmer med JavaScripts objektsyntax.


     
     
     
 {  "Name"  :  "Clem"  ,  "Id"  :  1234  ,  "Rank"  :  7  } 

Utan stöd för CORS resulterar ett försök att använda data över domäner i ett JavaScript-fel.

 
        
 <  script  type  =  "application/javascript"  src  =  "http://server.example.com/Users/1234"  >  </  script  > 

Webbläsaren laddar ner <script> -filen, utvärderar dess innehåll, misstolkar rå JSON-data som ett block och ger ett syntaxfel. Även om data tolkades som ett JavaScript-objektliteral, kunde det inte nås av JavaScript som kördes i webbläsaren, eftersom objektliterals är otillgängliga utan en variabeltilldelning.

I JSONP-användningsmönstret returnerar URL-begäran som pekas på av src -attributet i <script> -elementet JSON-data, med JavaScript-kod (vanligtvis ett funktionsanrop) omsluten. Denna "inpackade nyttolast" tolkas sedan av webbläsaren. På så sätt kan en funktion som redan är definierad i JavaScript-miljön manipulera JSON-data. En typisk JSONP-begäran och ett svar visas nedan.

Funktionsanropet till parseResponse() är "P" för JSONP - "utfyllnaden" eller "prefixet" runt den rena JSON. För att JSONP ska fungera måste en server svara med ett svar som inkluderar JSONP-funktionen. JSONP fungerar inte med JSON-formaterade resultat. JSONP-funktionsanropet som skickas tillbaka, och nyttolasten som funktionen tar emot, måste komma överens om av klienten och servern. Enligt konvention erbjuder servern som tillhandahåller JSON-data den begärande webbplatsen att namnge JSONP-funktionen, vanligtvis med namnet jsonp eller callback som den namngivna frågesträngsparametern, i sin begäran till servern: <script src="http:// server.example.com/Users/1234?callback=parseResponse"></script> .

I det här exemplet skulle den mottagna nyttolasten vara:

      parseResponse  ({  "Namn"  :  "Clem"  ,  "Id"  :  1234  ,  "Rank"  :  7  }); 

Skriptelementinjektion

JSONP är bara vettigt när det används med ett skriptelement. För varje ny JSONP-begäran måste webbläsaren lägga till ett nytt <script> -element eller återanvända ett befintligt. Det tidigare alternativet – att lägga till ett nytt skriptelement – ​​görs via dynamisk DOM-manipulation och kallas scriptelementinjektion . Elementet <script> injiceras i HTML DOM, med URL:en för den önskade JSONP-slutpunkten inställd som "src"-attributet. Denna dynamiska skriptelementinjektion görs vanligtvis av ett JavaScript-hjälparbibliotek. jQuery och andra ramverk har JSONP-hjälparfunktioner; det finns också fristående alternativ.

Ett exempel på att använda jQuery för att dynamiskt injicera skriptelement för ett JSONP-anrop ser ut så här:

 $  .  getScript  (  "http://server.example.com/Users/192.168.73.96?callback=parseResponse" )  ; 

Efter att elementet har injicerats utvärderar webbläsaren elementet och utför en HTTP GET på src URL, och hämtar innehållet. Sedan utvärderar webbläsaren returlasten som JavaScript. Detta är vanligtvis en funktionsanrop. På det sättet kan användningen av JSONP tillåta webbläsarsidor att arbeta runt samma ursprungspolicy via skriptelementinjektion.

Skriptet körs inom omfattningen av den inkluderande sidan och är som sådan fortfarande föremål för begränsningar över flera domäner i förhållande till domänen för den inkluderade sidan. Detta innebär att en webbsida inte till exempel kan ladda ett bibliotek som finns på en annan webbplats via JSONP och sedan göra XMLHttpRequest-förfrågningar till den webbplatsen (såvida inte cross-origin resource sharing (CORS) stöds), även om man skulle kunna använda ett sådant bibliotek för att göra XMLHttpRequests till sin egen webbplats.

Säkerhetsproblem

Otillförlitlig kod från tredje part

Genom att inkludera skriptelement från fjärrservrar kan fjärrservrarna injicera allt innehåll på en webbplats. Om fjärrservrarna har sårbarheter som tillåter JavaScript-injektion, utsätts sidan som serveras från den ursprungliga servern för en ökad risk. Om en angripare kan injicera valfritt JavaScript i den ursprungliga webbsidan, kan den koden hämta ytterligare JavaScript från vilken domän som helst, utan att principen för samma ursprung . Content Security Policy HTTP Header låter webbplatser berätta för webbläsare vilka domänskript som kan inkluderas från.

Ett försök gjordes runt 2011 för att definiera en säkrare strikt delmängdsdefinition för JSONP som webbläsare skulle kunna tillämpa på skriptförfrågningar med en specifik MIME- typ som "application/json-p". Om svaret inte analyserades som strikt JSONP kan webbläsaren skapa ett fel eller bara ignorera hela svaret. Detta tillvägagångssätt övergavs dock till förmån för CORS , och den korrekta MIME-typen för JSONP förblir application/javascript .

Skillnader i blanksteg

JSONP hade samma problem som att lösa JSON med eval() : båda tolkar JSON-texten som JavaScript, vilket innebar skillnader i hanteringen av U+2028 ( Line Separator ) och U+2029 ( Paragraph Separator ) från JSON. Detta gjorde att vissa JSON-strängar inte var lagliga i JSONP; servrar som betjänar JSONP var tvungna att undkomma dessa tecken innan överföringen. Detta problem har nu åtgärdats i ES2019.

Namnmanipulation för återuppringning och reflekterad filnedladdningsattack

Osanerade callback-namn kan användas för att vidarebefordra skadlig data till klienter, förbi begränsningarna förknippade med applikations-/json -innehållstyp, vilket demonstreras i reflekterad filnedladdning (RFD) attack från 2014.

Osäkra JSONP-slutpunkter kan också injiceras med skadlig data.

Förfalskning av begäranden på flera ställen

Naiva distributioner av JSONP är föremål för förfalskning av förfrågningar mellan platser (CSRF eller XSRF). Eftersom HTML <script> -elementet inte respekterar samma ursprungspolicy i webbläsarimplementeringar, kan en skadlig sida begära och få JSON-data som tillhör en annan webbplats. Detta gör att JSON-kodade data kan utvärderas i sammanhanget med den skadliga sidan, eventuellt avslöja lösenord eller annan känslig data om användaren för närvarande är inloggad på den andra webbplatsen.

Rosetta Flash

Rosetta Flash är en utnyttjandeteknik som gör att en angripare kan utnyttja servrar med en sårbar JSONP-slutpunkt genom att få Adobe Flash Player att tro att en angriparspecificerad Flash-applet har sitt ursprung på den sårbara servern. Flash Player implementerar samma ursprungspolicy som tillåter en att göra förfrågningar (med cookies) och ta emot svar från värdwebbplatsen. Appleten kan sedan skicka den hämtade datan tillbaka till angriparen. Detta är en cross-origin exploit med en effekt som liknar inbäddning av en godtycklig Flash-applet i den sårbara domänen. Exploateringen använder en ActionScript-nyttolast kompilerad till en SWF-fil som helt består av alfanumeriska tecken genom att skapa en zlib- ström med en viss rubrik och DEFLATE -block med ad-hoc Huffman-kodning . Den resulterande alfanumeriska SWF-filen används sedan som callback-parameter för ett JSONP-anrop. Högprofilerade webbplatser som Google, YouTube, Twitter, Yahoo!, Yandex, LinkedIn, eBay, Instagram och Tumblr var alla sårbara fram till juli 2014. Denna sårbarhet upptäcktes och publicerades av Googles säkerhetsingenjör Michele Spagnuolo och har CVE - 2014-4671 och CVE- 2014-5333 . Adobe Flash Player release version 14.0.0.145, släppt den 8 juli 2014, introducerade starkare validering av Flash-filer, och i version 14.0.0.176, släppt den 12 augusti 2014, slutförde korrigeringen, vilket förhindrade denna exploatering från att fungera.

Historia

I juli 2005 föreslog George Jempty att en valfri variabeltilldelning skulle läggas till JSON. Det ursprungliga förslaget för JSONP, där utfyllnaden är en återuppringningsfunktion , verkar ha gjorts av Bob Ippolito i december 2005 och används nu av många Web 2.0- applikationer som Dojo Toolkit , Google Web Toolkit och webbtjänster .

Se även

externa länkar