Komentáře k článku

Cross-Site XMLHttpRequest

Cross-Site XMLHttpRequest nebo též Cross-Origin Resource Sharing (CORS) je nová a zatím nepříliš rozšířená technika, která může pomoci řešit problémy s přístupem k datům třetích stran z webových aplikací. Pokud potřebujete do své aplikace získat data odjinud, může se hodit i vám. Blíže si CORS představíme v článku.

Zpět na článek

43 komentářů k článku Cross-Site XMLHttpRequest:

  1. huh

    JavaScript je nejoblíbenějším programovacím jazykem webových aplikací

    Javascript je jediný jazyk, který běží v prohlížeči. Kdybych si mohl vybrat, tak bych používal radši skoro cokoli jinýho, snad kromě APLu.

    1. David OndřichAutor příspěvku

      Re: JavaScript je nejoblíbenějším programovacím jazykem webových aplikací

      Minimálně je tu ještě VBScript. :-)

      1. Ped

        Re: JavaScript je nejoblíbenějším programovacím jazykem webových aplikací

        On myslel programovaci jazyk. :)

          1. Ped

            Re: JavaScript je nejoblíbenějším programovacím jazykem webových aplikací

            Ja sarkasticky narazel na kvalitu VBscriptu. I kdyz to ode mne neni fer, nakonec za to co vznikne je odpovedny hlavne tvurce, ale nekdy mi to prijde ze VB vyslovene taky-programatory pritahuje. No dobre, byl to laciny a trapny pokus o vtip, uznavam. (mne se ostatne casto zveda zaludek i z nekterych jscriptu ktere na webu vidim, takze prast jako uhod)

  2. Michal Augustýn

    Re: Cross-Site XMLHttpRequest

    Přijde mi to trošku zvláštní (ale třeba mě někdo přesvědčí o opaku), ale znamená to, že request prohlížeč provede VŽDY, ale až teprve podle přítomnosti hlavičky rozhodne, jestli data předat dále?
    Ale možnost určit, kdo smí využívat mé služby, se zdá docela rozumná (ačkoliv je to je „dobrá vůle“ prohlížeče, jestli předá data dále)…

    1. David OndřichAutor příspěvku

      Re: Cross-Site XMLHttpRequest

      Ano, Firefox 3 a 3.5 to přesně takhle dělá. Pokud si správně pamatuju, jak se chovalo IE7 při testování, tak to bylo stejné.

    2. soudruh

      Re: Cross-Site XMLHttpRequest

      Také jsem to takto špatně napřed pochopil, ale zde jde o hlavičku kterou odešle webový server scriptu, ne webový server dat.

    1. brut4r

      Re: IE8 a jeho XDomainRequest

      Je to stejne dokonce to vyzaduje tu hlavicku Access-Control-Allow-Origin, a podle textu je to postavene na tom samem standardu. Takze IE8 uz to umi taky ;)

    2. David OndřichAutor příspěvku

      Re: IE8 a jeho XDomainRequest

      Je to to samé, díky za doplnění; při psaní článku mi to uniklo, narazil jsem na to až včera v souvislosti s WebClient objektem v Silverlightu…

  3. Borek Bernard

    Proč je cross-site request nebezpečný?

    Nerozumím, jaký problém se za mě prohlížeče snaží vyřešit tím, že JavaScriptu znepřístupní data z cizích domén. Co by se stalo, kdyby hypoteticky všechny prohlížeče zítra přestaly kontrolovat původ?

    1. ah01

      Re: Proč je cross-site request nebezpečný?

      Předpokládejme, že protože by se jednalo o regulérní požadavek na danou doménu, posílalo by se v hlavičce i cookie, tedy i SessionID a podobně. No, a pokud by byl dotyčný návštěvník na cílové aplikaci přihlášený…

      Mohl bych pak na stránku umístit kód, který by uměl u návštěvníka přihlášeného na Gmailu stáhnout veškerou jeho poštu.

      Navíc, stejná Same Origin Policy se týká i přístupu k iframu z jiné domény. Takže bych mohl na stránku umístit skrytý iframe, nahrát do něj Gmail a doslova si s ním dělat co chci.

      1. Borek Bernard

        Re: Proč je cross-site request nebezpečný?

        Proč by se s každým požadavkem kamkoliv měly posílat i cookies? Např. při navštívení twitter.com se v hlavním HTTP požadavku pošle auth_token cookie, ale při požadavcích na obrázky z domény xyz.twimg.com se autentizační cookie přirozeně neposílá.

        Nejsem žádný bezpečnostní expert, ale zdá se mi, že popisujete běžný XSS, který funguje nezávisle na kontrolování Same Origin. Nebo se pletu?

        1. Envel

          Re: Proč je cross-site request nebezpečný?

          Zkus si představit, že jsi přihlášen do webové aplikace A, která obsahuje na určité stránce pro tebe citlivá data. Co by se stalo, kdybys vstoupil na stránku, která by posílala request aplikaci A s žádostí o tvá citlivá data? Jsi-li přihlášen, podle HTTP protokolu bys odeslal i cookie a skript by získal tvé údaje. To samozřejmě nikdo nechce. Samozřejmě mluvíme o možnosti, že jsi do původní aplikace přihlášen.

          Jinak cross-site request pouze zjednodušuje některé způsoby zneužití XSS chyb.

          1. Borek Bernard

            Re: Proč je cross-site request nebezpečný?

            Ok, ve Firefoxu jsem přihlášen v aplikaci A na doméně a.example.com, ta pomocí JavaScriptu načítá data z URL http://a.example.com/api.php a tento PHP skript kontroluje uživatele pomocí cookie ‚SID‘. Na nové záložce otevřu web http://mallory.example.com/index.php – web útočníka. Ten chce získat citlivá data z URL http://a.example.com/api.php – v současnosti je přímý request na toto URL pomocí JavaScriptu nemožný, kdyby však možný byl a neposílaly se cookies (stejně jako se tak neděje třeba při načítání obrázků z jiné domény), jak by byly moje data ohroženy? Skript api.php by zjistil, že součástí požadavku není SID cookie a vrátil by nějakou chybu, jak se ostatně stane, když web útočníka nezaútočí přes JavaScript, ale třeba přes serverové PHP volání.

            Patrně mi uniká nějaký „detail“ s posíláním cookies – zdá se, že ty i Adam jaksi předpokládáte, že se cookies pošlou, a já si nejsem jistý, z čeho tento předpoklad vychází. V příkladu, co jsem uvedl, nevidím žádný důvod, proč by se měly posílat a celý systém tak udělat zranitelný.

            1. David OndřichAutor příspěvku

              Re: Proč je cross-site request nebezpečný?

              Protože předpokládáte, že útočí obránce.

              Váš skript A ale naopak může obsahovat útok na citlivá data z mallory.exam­ple.com – pokud budete JSON deserializovat pomocí eval(), snadno si spustíte z cizí domény kus kódu, který se vám pohrabe v aplikaci a potřebné údaje si pošle zpět na a.example.com. O cookies v tomhle případě nejde, jde o to, že vkládaná data jsou potenciálně nebezpečná.

              Je to jasnější?

              1. Borek Bernard

                Re: Proč je cross-site request nebezpečný?

                Popravdě mi pojmy jako „útočící obránce“ nebo prohození záškodnosti a.example.com a mallory.example.com do případu mnoho světla nevnášejí :) Pokud vás ale chápu dobře, říkáte, že bez Same Origin Policy bych si mohl do své aplikace natáhnout skript z cizí domény a spustit ho pomocí eval(), čímž by se mi mohla stát řada nepříjemných věcí. To souhlasím, ale současně musím něco takového čekat, když dělám eval() na cizím nedůvěryhodném kódu, ne? Je to asi jako ve Windows spustit EXE soubor – „hodné“ programy mi pomůžou, ty zlé mi můžou ukrást data, naformátovat disk a podobně. Je na mě, jestli kód spustím nebo ne, nevidím v tom principiální problém.

                Asi by pomohlo, kdyby někdo popsal nějaký hypotetický útok při absenci Same Origin Policy od začátku do konce. Třeba jak bych kvůli tomu mohl přijít o emaily v GMailu.

                1. David OndřichAutor příspěvku

                  Re: Proč je cross-site request nebezpečný?

                  Fajn, zkusím to popsat. Od začátku předpokládám, že se SOP v prohlížeči neřeší. Aplikace běží jen v klientovi, na server se posílají pouze data v JSONu.

                  Mám webovou aplikaci běžící na doméně A, která slouží např. pro zadávání dat do databáze. Obsahuje několik formulářů s mnoha položkami. Některé z těch položek představují logickou vazbu do existujících externích aplikací – dejme tomu, že existuje nějaký veřejný registr identifikačních čísel (např. čísel občanek), z nich pouze některá jsou správná. Moje aplikace potřebuje na několika místech validovat ta čísla. Provozovatel registru B mi usnadnil život, nabízí veřejné API, které umožňuje správnost čísla ověřit.

                  Abych nemusel pro každé zadání toho identifikátoru volat API registru (všimněte si, že se současnou SOP ani tohle nemůžu), můžu využít super-hyper-cool funkci API registru, kdy si namísto odpovědi na test true/false vyžádám funkci, které pak každý identifikátor předám jako parametr a ona v klientu vyhodnotí jeho (ne)správnost. Nezajímá mě, jak se pozná správnost toho čísla a nechci to zkoumat, od toho je tu to API. Dokud věřím, že ta funkce dělá jen to, co má, je to v pořádku. Ale jenom tomu věřím; pokud API registru někdo crackne, snadno získá vládu nad všemi dat v mé aplikaci.

                  Ano, příklad je přitažený za vlasy, vím. Lepší mě narychlo nenapadl.

                  Pro váš GMail: dejme tomu, že Gůgl a prohlížeč umožní tvorbu super plug-inů do GMailu; vy si budete chtít spustit plug-in, který zkontroluje český pravopis (Gůgl neumí dobše chésky, ale hodní hoši z firmy CzechskyEasy&Fast připravili skvělý modul), nebo takový, který všechny obrázky v mailech nahradí jejich zkarikovanými variantami (ano, jsou lidé, co chtějí dělat takové kraviny). V obou případech spouštíte legitimní kód někoho jiného, který má v tu chvíli absolutní vládu nad GMailem.

        2. Daniel Steigerwald

          Re: Proč je cross-site request nebezpečný?

          Borku, takových požadavků lze udělat více druhů, problém je 1) objem dat a 2) bezpečnost. Požadavkem na obrázek získáš tak maximálně jeho rozměry (v IE, Canvas by jej naparsovat uměl). V připojeném CSS stylu, v background-image např. už by se něco dat vešlo :) Avšak do stylů lze vložit script, tak fungoval myspace Samy worm. Připojit lze i script přímo, tak funguje JSON-P, avšak načtení cizího scriptu je krajně nebezpečné. Zbývá tedy XHR a IFrame. XHR popisují ostatní komentující. Dva iframe z různých domén se sice navzájem poškodit nemohou, komunikace však možná je. 1) zápisem do location hash 2) hack window.name První případ se dříve často používal, nejedná se totiž o neopravenou bezpečností chybu. Bohužel někdo hooodně moc hloupý v MS rozhodl, že prohlížeč IE7 bude mít skvělou vlastnost → klikne při změně url. Tohle v JS nejde vypnout, jedině obejít tak, že pro každou správu se vytvoří nový iframe, a location nastaví ještě před vložením do stránky.. to je ale děsně neefektivní způsob. Hack pro window.name používá např. Dojo. Je to divné, ale takto lze přenést až deset mega v jedné zprávě. V praxi se tedy musí použít způsob jiný. Odpověď na tvou otázku tedy zní, pokud by někoho napadlo při návrhu XHR volitelně neposílat cookie, pak by nebylo nutné XHR jakkoliv omezovat.

    2. Martin Straka

      Re: Proč je cross-site request nebezpečný?

      V článku je to myslím také nepřesně podané. Jde hlavně o (ne)přístup k datům z jiných domén a jedná se možná o nejdůležitější koncept v oblasti bezpečnosti použitý v prohlížeči. Izoluje aplikace od sebe navzájem.

      Kdyby to prohlížeče nedělaly, tak by například vůbec nefungovala obrana proti XSRF (CSRF) založená na tokenu ve stránce:

      http://php.vrana.cz/…-forgery.php http://zdrojak.root.cz/…k-se-branit/

      protože by si ho útočící stránka jednoduše přečetla:) a dalších příkladů se dá uvést spousta.

      Občas v tom prohlížeče mají chybu (taky jsem jednu reportoval do Firefoxu) a to je pak nepříjemné a z hlediska provozovatele aplikace se proti tomu špatně brání.

      Jako dobrý zdroj na studium bych doporučil Browser security handbook od Michala Zalewskiho:

      http://code.google.com/…c/wiki/Part2#…

      1. David OndřichAutor příspěvku

        Re: Proč je cross-site request nebezpečný?

        Ano, z hlediska prohlížečů jde o nepřístup k datům z jiných domén. Myslím si, že to je důsledek návrhu, jak je implementovaný JS v prohlížeči, kdy hlavní objekt window může v paměti přetrvávat dlouho po „ukončení“ webové aplikace. Izolace jednotlivých kontextů je pak jediná možnost, jak zabránit přístupu do cizího kódu/dat; je to ovšem jenom můj názor, detaily implementace JS jsem nikdy nestudoval. A jak psali Adam Hořčica a Envel, skutečně nejde o nic jiného, než jednodušší formu XSS.

        Z hlediska aplikace jde naopak o zpřístupnění dat např. při tvorbě mashupů, u které je naopak přístup k „cizím“ datům žádoucí a potřebný.

      2. Borek Bernard

        Re: Proč je cross-site request nebezpečný?

        Dík za tip na Browser sercurity handbook, počtu si, až budu mít čas.

    3. Jakub Vrána

      Re: Proč je cross-site request nebezpečný?

      Jak už bylo uvedeno, tak se tím brání získávání citlivých dat. Ve většině případů by asi stačilo, aby se na cizí doménu neposílaly cookies a HTTP autentizace, ale zdaleka ne vždy. Někdy je zcela v pořádku chránit stránku jen podle IP adresy uživatele, chránit před CSRF je potřeba třeba i anketu pro nepřihlášené uživatele. Pro tyto dva případy by cross-site request byl nebezpečný, i kdyby se neposílaly cookies a HTTP autentizace.

      1. Borek Bernard

        Re: Proč je cross-site request nebezpečný?

        Je tedy obrana proti CSRF jedním z hlavních use-casů, kde by se absence kontroly Same Origin projevila nejvíce? Čekal jsem něco očividnějšího a u příspěvků výše, které mluví o jakémsi session hijacking, pokud používám správný termín, si přesnou anatomii útoku pořád nedokážu představit.

        1. Jakub Vrána

          Re: Proč je cross-site request nebezpečný?

          Jde o to, že při absenci same-origin by útočník mohl získat všechna data a provést všechny operace na všech webech jménem uživatele, který přijde k němu na stránky.

            1. Jakub Vrána

              Re: Proč je cross-site request nebezpečný?

              Jak jsem psal ve svém původním příspěvku – pokud by veškeré autorizace byly založeny na cookies, tak by pouhé neposílání cookies problém vyřešilo. Ale někdy je autorizace založena třeba jen na IP adrese nebo v případě anket pro nepřihlášené uživatele ani na tom. Navíc cookie nemusí udržovat jen informaci o přihlášení, takže neposlání cookies by mohlo způsobit nevhodnou reakci webu.

            2. Martin

              Re: Proč je cross-site request nebezpečný?

              Nejde pouze o javascript x-site requesty. Další příklad aplikování same-origin policy jsou například otevřená okna, framy/iframy, nadřízená okna a jejich (ne)přístup z javascriptu plus nespočet dalším možností jak se k DOM stránky dostat.

              Pokud nejsou ze stejné domény tak také nemají přístup k této stránce, nemohou z ní číst, ani ji modifikovat. Pokud je stránka v jiném okně/framu/iframu ze stejné domény (pominul jsem další věci, jako stejný port, protokol) může ji javascript libovolně číst nebo modifikovat.

              Například díky same origin policy si nemůžu číst poštu v okně které není moje (jiná doména) když by obět náhodou byla přihlášená:

                seknam = window.open('http://email.seknam.cz/folderScreen');
              
                ...
              
                alert(seknam.document.getElementById('message1').innerHTML);
              1. Daniel Steigerwald

                Re: Proč je cross-site request nebezpečný?

                Jen doplním, dva iframe z různých domén si mohou zapisovat do location hash. Kdyby někoho v MS nenapadlo, že IE7 má při každé změně location klikat, mohly jsme dávno používat tuhle techniku zapouzdřenou v JS knihovnách. Momentálně se používá window name, ale této technice moc nevěřím.., co když někoho v MS napadne to „opravit“..

    4. rtgfv

      Re: Proč je cross-site request nebezpečný?

      blokovat ajaxovej request na cizi domenu je naprosta kokotina, mimochodem to drive dokonce i fungovalo nevim jestli v ie6 nebo ve ff 1.5.. kdyz si bude chtit utocnik odeslat javascriptem citliva data ma mnoho jinych zpusobu nez pouzit ajax

  4. NG

    Cross-site request funguje

    Zdravim, možná teď některé z vás překvapím, ale cross-site requesty fungují ve všech dnes používaných prohlížečích a není k tomu potřeba měnit jakékoliv nastavení prohlížeče. Stačí jen místo XMLHttpRequest použít jiný postup. Na základě této „finty“ fungují všechny JavaScript API od Googlu a jiných. Jinak by ani nešly dělat mash-up aplikace, které průběžně (AJAXově, chcete-li) dostávají data z jiné domény. Přijde mi to, že je to veřejné tajemství, o kterém se nemluví. Že by to někdo v budoucnu omezil je dost nepravděpodobné, protože by přestalo fungovat spoustu věcí a to si nikdo nedovolí udělat.

    1. Martin Malý

      Re: Cross-site request funguje

      Myslím že to pro nikoho překvapením nebude. Klíčové slovo je JSON-P, v článku je odkaz a na odkazu vysvětlení – to je ta finta, ne? „Veřejné tajemství, o kterém se moc nemluví“ není nic jiného než skriptem vytvořený DOM element SCRIPT se SRC nastaveným na JSON-P datový zdroj.

      1. NG

        Re: Cross-site request funguje

        Sorry, přehlédl jsem a ano, to je ta finta. Nicméně to, že tento způsob a hlavně jeho uplné využití není moc známe je zřejmé jak z minimální zmínky v článku, tak z komentářů v této diskuzi. A neznají to ani „profesionálové“, neb vytřeštěné oči zaměstnanců několika velkých integrátorů v ČR jsem už bohužel viděl. Obecně se totiž povědomí o této problematice pohybuje ve dvou extrémech – všechno je možné (pak údiv nad tím, že si IFRAME nebo okno z jiné domény s parentem nepopovída) a nic není možné (pak zase údiv nad tím, že to vlastně jde).

        Navíc věta: „Hlavní nevýhoda tohoto postupu je v tom, že na zpracování kódu v klientské aplikaci spuštěné z vašeho serveru musel myslet tvůrce služby, která poskytuje data.“

        by se měla zarámovat, ale v opačném smyslu, protože když na to tvůrce služby myslel, tak vytvořil nějaké API a to je možno považovat za kontrakt mezi poskytovatelem služby a jejím uživatelem. V opačném případě chcete konzumovat něco, co třeba druhá strana ani nepředpokládala, že někdo použije, tj. může to kdykoliv nekompatibilně změnit, zrušit, atp.

        1. Daniel Steigerwald

          Re: Cross-site request funguje

          JSON-P je díra jak hrom. Můžu jej použít, pouze pokud je poskytovatel velmi důvěryhodný. A pokud někdo hackne jej, mám smůlu. Opravdu bezpečné čistě javascriptové jsou pouze dva způsoby, které jsem popsal výše.

          1. NG

            Re: Cross-site request funguje

            „JSON-P je díra jak hrom.“ je podle mne hodně silné tvrzení. Ano, je problém v tom, že když se z hodného poskytovatele stane zlý, což se může stát hacknutím jeho serveru. Když se tak stane, tak je na mne, jestli to vyhodnotím jako důvod pro změnu poskytovatele. Z opačného pohledu stejně tak dobře může někdo hacknout i můj server. BTW víte, kolik úspěšných útoků zaměřených na JSON-P proběhlo v poslední době?

        2. David OndřichAutor příspěvku

          Re: Cross-site request funguje

          Tenhle článek není, proto je v něm „minimální zmínka“.

          Co se týče API a jeho poskytovatele a konzumenta: nepodléhejte dojmu, že když někdo poskytuje (REST) API, jediným klientem je webový prohlížeč. Z vlastní zkušenosti naopak soudím, že to je minoritní přístup – nejčastějším klientem je buď desktopová aplikace nebo především jiný server. Ani pro jednoho není vůbec žádný problém vytvořit HttpRequest kamkoliv, takže tvůrce toho API něco jako JSON-P vůbec nezajímá.

          1. David OndřichAutor příspěvku

            Re: Cross-site request funguje

            Ach jo: O JSON-P tenhle článek není, proto je v něm pouze „minimální zmínka“.

          2. NG

            Re: Cross-site request funguje

            Dle odstavců „Chci data odjinud!“ a „Nechci slyšet, že to nejde“ jsem tak nějak nabyl dojmu, že se článek zmiňuje i o tom, jak dostat data z jiné domény. Textu je tam na toto téma dost.

            Když tak nad tím přemýšlím, tak místo těch dvou zmíněných odstavců tam mohla být jen krátká zmínka o proxy (možná pro většinu relativně složité/kompli­kované); IFRAME snad ani nezmiňovat, protože to se s cross-site vůbec nerýmuje; a spíš popsat způsob, jak to jde udělat i se stávajícími prohlížeči (a třeba i včetně poznámky, že jisté bezpečnostní rizika tam jsou).

            Ad API pro web, desktop a server) V tomto případě jsem uvažoval jen konzumenta v podobě webu – asi proto, že ten článek je o cross-site, který desktop ani server nezajímá.

            1. David OndřichAutor příspěvku

              Re: Cross-site request funguje

              Výborně, takže si to srhneme.

              Protože jste „nabyl dojmu“ ze dvou odstavců, získal jste pocit, že článek je o něčem, o čem není. Doporučuju číst celý text, dokonce včetně nadpisu a perexu. Diskuze o JSON-P patří pod odkazovaný článek, a to včetně bezpečnostních ri­zik.

              Dále, prohlásil jste: „protože když na to tvůrce služby myslel, tak vytvořil nějaké API … [které] chcete konzumovat[, tedy] něco, co třeba druhá strana ani nepředpokládala, že někdo použije“. Oponoval jsem, že tvůrce služby často vytvoří obecné API, které vyhovuje standardům (např. REST), aniž by přitom zohlednil potřeby minoritní skupiny klientů (=webových prohlížečů). To ale vůbec neznamená, že když nad API chcete postavit webovou aplikaci, používáte rozhraní jinak, než tvůrce předpokládal. Je jen a pouze chybou prohlížečů, že nemohou pracovat přímo s tím rozhraním, ale potřebují k tomu nějaké berličky v podobě JSON-P nebo CORS.

              To je konzistentní s tvrzením v článku, kde stojí: „…na zpracování kódu v klientské aplikaci spuštěné z vašeho serveru musel myslet tvůrce služby, která poskytuje data. Pokud se tak nestalo, máte smůlu…“

              1. NG

                Re: Cross-site request funguje

                Ach jo… Původně jsem napsal, že „Obecně cross-site funguje a že stačí jen místo XMLHttpRequest použít jiný postup.“ Tím jsem reagoval na dva odstavce v článku. Od teď díky Vám vím, že musím vždy reagovat na celý článek. Děkuji.

  5. _

    Nemožnosť získať cudzí HTML kód

    Pokiaľ viem, tak doteraz sa nedalo z hľadiska bezpečnosti pracovať v JavaScripte s cudzím HTML kódom.
    Dalo sa pracovať s cudzím JavaScriptom, CSS, obrázkami, …, no nie s cudzím HTML kódom.
    Ten spôsob uvedený v článku by mal asi umožniť aj toto, pokiaľ to server povolí.

Napsat komentář

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: https://www.zdrojak.cz/?p=3074