Hlavní navigace

Vlákno názorů ke zprávičce Bezpečnostní díra v Java knihovně ohrožuje stovky aplikací od Kolemjdoucí - Ona to totiž ve skutečnosti není chyba, protože...

  • Aktualita je stará, nové názory již nelze přidávat.
  • 9. 11. 2015 9:41

    Kolemjdoucí (neregistrovaný) ---.tunnel.tserv27.prg1.ipv6.he.net

    Ona to totiž ve skutečnosti není chyba, protože se to projevuje pouze pokud uživatel má možnost změnit serializovaná data která následně aplikace bude deserializovat a při tom spustí to co si tam uživatel podvrhnul. Pokud někdo uživateli umožňuje přímo měnit serializovaná data tak je to chyba v návrhu, protože tím dává uživateli asi tak milion možností jak toho zneužít, není důvod se vzrušovat kvůli této jedné konkrétní...

  • 9. 11. 2015 10:11

    Filip Jirsák

    To, že uživatel má možnost podstrčit data k deserializaci není chyba návrhu. Vždyť jsou to jenom data. Když uživatel na webu odešle formulář, odesílá tím data k deserializaci. Už jenom zadání URL na webu jsou data k deserializaci – i když se v případě toho URL ani formuláře nedeserializuje Java serializací ale textová reprezentace.

    Problém by mohl být, pokud by deserializovaná třída ta přijatá data chybně interpretovala. Což teoreticky je možné. Ke spuštění cizího kódu by to ale znamenalo, že ta data bude interpretovat jako skript a spustí jej, nebo že ta data bude interpretovat jako bajtkód a vytvoří na jeho základě třídu, kterou poté nahraje. Což samo o sobě není vůbec jednoduché – a uvedená třída InvokerTransfor­mer nejen, že nic takového nedělá, ona vůbec neimplementuje vlastní deserializaci.

    Zneužitelné je pouze to, pokud by někdo serializoval a deserializoval instanci té třídy InvokerTransformer, a útočník pak může změnit jenom to, kdy v případě, že se ten deserializovaný InvokerTransformer zavolá na nějakou instanci, může útočník změnit volanou metodu (na stejné instanci) a její parametry. Zaútočit by se tedy dalo jen na konkrétní kód chybně využívající té třídy, rozhodně ne na jakoukoli aplikaci tu třídu využívající. A útok by spočíval jen ve spuštění jiného kódu na dané třídě, nelze tím spustit libovolný kód útočníka.

  • 9. 11. 2015 10:20

    Kolemjdoucí (neregistrovaný) ---.tunnel.tserv27.prg1.ipv6.he.net

    Napsal jsem "Pokud někdo uživateli umožňuje přímo měnit serializovaná data tak je to chyba v návrhu" a tím "přímo" jsem myslel měnit rovnou ty serializované bajty, takže třeba změnit třídu a podobně, to je základní princip této "chyby". Měnit data která uživatelem měnitelná být musí samozřejmě není nic špatného, ale všechna data od uživatele musí jít skrz patřičné aplikační kontroly a ten serializovaný formát pak musí být striktně interní, na něj uživatel nesmí sahat protože by tím obešel ty všechny kontroly.

  • 9. 11. 2015 10:32

    Filip Jirsák

    U každé aplikace, která posílá přes síť data serializovaná pomocí standardní Java serializace (třeba RMI), může uživatel přímo měnit serializovaná data. Aby to bylo zneužitelné, musí ještě někdo na těch uživatelem podstrčených datech zavolat nějaký kód, který provede nějakou neplechu.

    Například pokud bych měl třídu, která má field typu Runnable, serializovanou instanci této třídy bych získal od uživatele a měl bych někde v aplikaci implementaci Runnable, která zavolá System.exit() (a měl bych tohle volání povolené v politice), může mi uživatel do serializovaných dat místo mnou očekávána instance Runnable podstrčit tu, která volá System.exit(). Ale pokud něco takového ty exploity dělají, není to nikde v tom doprovodném textu napsáno a není tam ani napsáno, ve které třídě je chyba.

  • 9. 11. 2015 12:21

    Starous (neregistrovaný) ---.eurotel.cz

    nakolik mě tedy má tento možný exploit trápit nebo není tak velké riziko to vyignorivat ?

  • 9. 11. 2015 13:33

    Karel (neregistrovaný) 93.90.162.---

    To v této chvíli nikdo neví, nebylo zveřejněno dost informací. Podle některých spekulací se jedná o stejný "exploit" jako když webová stránka odněkud stáhne javascript a ten spustí. Jinými slovy - klient si odněkud stáhne data, což je naprosto běžný postup. A pak je otázka ta, zda autor nějaké knihovny měl tak skvělý nápad, že ta data označí za spustitelný kód a spustí ho. Pokud to tak je, pak útočník může pozměnit přenášená data a tím podvrhnout kód, který se pak spustí.

    Jenže nevíme, o jakou knihovnu jde, takže těžko to ověřit. V každém případě Java to v základu neumí, do dat/z dat načítá jen hodnoty atributů, nikoliv bytekód. Ale jde napsat program takový, aby si bytekód tahal a spustil. Běžně se to používá, ale vyžaduje to netriviální úsilí (viz ClassLoader) a autor by si tak měl být vědom toho, že stahuje bytekód, který pak spouští. Včetně úvah nad tím, zda to stahuje z důvěryhodného zdroje.

  • 9. 11. 2015 17:58

    Ondrej Mikle (neregistrovaný) 2001:1488:fffe:----:----:----:----:----

    Ta zpráva vyjmenovává několik příkladů zranitelných aplikací: WebLogic, WebSphere, JBoss, Jenkins, OpenNMS.

    Zranitelné jsou, pokud mají přístupný port, na kterém běží služba používající problematickou deserializaci.

    Ověřit to lze, přímo původní článek obsahuje HOWTO i odkaz na repozitář s exploit kódem.

    Ono to celé není nová zranitelnost, to samé bylo předvedeno předtím v práci "Marshalling Pickles" (https://www.youtube.com/watch?v=KSA7vUkXGSg). Nové na tom je jen našroubování exploitu na existující aplikace.

  • 9. 11. 2015 18:24

    Filip Jirsák

    Zranitelné jsou, pokud mají přístupný port, na kterém běží služba používající problematickou deserializaci.
    Důležité také je, zda k té deserializaci dochází před autentizací uživatele, případně zda se rozlišují úrovně oprávnění, nebo pokud je komunikace nešifrovaná a útočník ji může pozměnit (což by ale byl větší problém, než ta deserializace). Pokud je ta problematická služba určena pouze pro administrátory, není to kritické – pokud administrátor sám sobě úmyslně shodí server, je to jeho chyba, a má k tomu ostatně mnoho jiných příležitostí, než hackovat deserializaci.

    Ověřit to lze, přímo původní článek obsahuje HOWTO i odkaz na repozitář s exploit kódem.
    Vzhledem ke zmatenosti toho příspěvku oznamujícího chybu bych byl velmi opatrný při spouštění kódu, na který ten příspěvek odkazuje.

  • 9. 11. 2015 22:59

    Jiri Korbel (neregistrovaný) ---.net.upcbroadband.cz

    Otazka znela, zda to lze overit. Ano, lze. Fakt, ze s libovolnym exploit kodem se musi zachazet velmi opatrne, je snad uplne jasny.

  • 9. 11. 2015 13:46

    Filip Jirsák

    No, to by mne také zajímalo. Ta chyba teoreticky existovat může. Knihovna Apache Commons Collections by v takovém případě vystupovala spíše jako nástroj útoku než jako zdroj té bezpečnostní chyby. Každopádně ten odkazovaný popis je velmi zmatený a nepopisuje samotný princip chyby, to by se muselo zjistit reverzním inženýrstvím toho exploitu. Existují už nějaké záplaty k té chybě (třeba pro Groovy), takže reálný základ to asi má. Ale nevím, jestli už existuje nějaký seznam tříd, které jsou k téhle chybě zneužitelné.

    Správné řešení tohohle problému spočívá v tom, že nemůžete deserializovat třídu podle názvu, který vám mohl někdo podstrčit, ale vždy musíte při té deserializaci předem vědět, jaký typ objektu (nebo typy) očekáváte a musíte kontrolovat, že někdo nepodstrčil něco jiného.

    Každopádně chyba je zneužitelná jenom tehdy, pokud má útočník možnost podvrhnout serializovaná data, tedy typicky pokud jde o klient-server aplikaci, kde klient předává serveru objekty serializované pomocí Java serializace – tedy ne třeba přes XML nebo JSON (ale pozor na to, že ty serializované objekty klidně mohou být přenášené třeba přes HTTP).

  • 9. 11. 2015 14:06

    Karel (neregistrovaný) 93.90.162.---

    Tak jméno mi může podstrčit jaké chce. Když mi místo com.company.Em­ployee pošle com.company.Sup­plier, tak na to asi přijdu při kontrole typu, případně mi to rovnou spadne na chybu přetypování. Přeci jen zavolat funkci typu "deleteAllEmplo­yees" na objektu typu Object nejde. Navíc podvrhnout může jen existující třídu, protože jinak spadne na ClassNotFoundEx­ception. A na té existující musí existovat metoda, kterou program volá a musí se trefit do přetypování, které programátor použil (tady by Interface mohl útočníkovi pomoci).

    Podstatné je, že mi přes serializaci nedokáže poslat spustitelný kód, jen data. Deserializace použije kód z classpath a jen doplní data podle příchozího souboru. Čili dokáže v ideálním případě leda tak zajistit, že se spustí metoda jiné třídy, než by měla. Útok typu, že si serializuji záznam o zaměstnanci, v něm přepíšu plat na desetinásobek a pak deserializuji, je natolik zřejmý, že o ten asi nepůjde.

    Pokud ale nějaká knihovna použije data jako program (vlastní ClassLoader), pak to samozřejmě problém je poměrně zásadní.

  • 9. 11. 2015 14:48

    Filip Jirsák

    Chytřejší útočník samozřejmě nepodstrčí náhodně zvolené jméno, ale jméno třídy, kterou je možné přiřadit do příslušného typu. Uváděl jsem příklad s Runnable, případně třídy, které pracují s reflexí. Samozřejmě, možnosti útočníka jsou celkem omezené a nemůže volat vlastní kód, ale jen kód, který už je přítomný v aplikaci.

  • 9. 11. 2015 23:29

    Cohen (neregistrovaný) ---.net.upcbroadband.cz

    Myslím, že pokud deserializujete data, která může útočník upravit, otevírá to úplně jiný prostor pro případný exploit, než klasické vstupy. A nikoliv jen to, co popisujete. Zvláště pokud máte otevřený kód, tak lze hledat cesty, kdy pošle útočník záměrně nevalidní obsah objektu tak, aby zneužil něčeho, co by se za běžného provozu vůbec nemohlo stát, protože se počítá s tím, že je objekt generován standardní cestou.

    Nemám s Javou širší zkušenosti, ale v .Netu můžete třeba plnit nějakou dostatečně volně typovanou proměnnou, tj. např. object, nebo něco zdědit a v rámci deserializace dosáhnout načtení externího typu. Ale to je dost hypotetický příklad.

  • 9. 11. 2015 13:22

    Kolemjdoucí (neregistrovaný) ---.tunnel.tserv27.prg1.ipv6.he.net

    "U každé aplikace, která posílá přes síť data serializovaná pomocí standardní Java serializace (třeba RMI), může uživatel přímo měnit serializovaná data." - je snad nepochopitelné to co jsem napsal, tedy že toto je zásadní chyba v návrhu? Uživatel se k serializovaným datům vůbec nemá dostat! Co jsem koukal tak toto dělají různé managementové nástroje, ale tam to zase je až po autorizaci administrátora takže to je snad OK. Kdo takhle řeší koumunikaci s běžnými uživateli tak to má prostě blbě navržené a chyb z toho plyne spousta, nemá smysl je pitvat jednu po druhé...

  • 9. 11. 2015 13:51

    Karel (neregistrovaný) 93.90.162.---

    Takhle to funguje už od dob RPC. Dnes to tak používá obrovské množství protokolů. V čem přesně je podle vás chyba? Jsou to prostě jen data, žádný kód. A protože se to posílá přes TCP/IP, tak to prostě klient i server mohou modifikovat. Nasazení šifrování zabrání ve změnách na cestě, ale oba konce si to mohou změnit jak chtějí.

  • 9. 11. 2015 15:14

    Kolemjdoucí (neregistrovaný) ---.tunnel.tserv27.prg1.ipv6.he.net

    Chyba je v tom že to serializační API které je v Javě (které používá metodu readResolve) je k tomuto nevhodné protože neposkytuje potřebné validační mechanismy a navíc neplatí to co píšete "Jsou to prostě jen data, žádný kód" - viz popis té zranitelnosti. Samozřejmě není nic špatného na tom když klient posílá na server serializovaná data, jen je k tomu potřebné použít patřičný serializační mechanismus na straně klienta a validace na straně serveru. Běžně se používají v kombinaci s HTTP např. parametry v URL s metodou GET, nebo nějak naplněné tělo s metodou POST (např. JSON nebo XML), ale kdo tam nacpe tu Javovskou serializaci tak to holt dělá špatně a nadávat za všechny problémy může jen sám sobě protože ten nástroj použil nevhodným způsobem.

  • 9. 11. 2015 14:02

    Filip Jirsák

    Uživatel se k serializovaným datům vůbec nemá dostat!
    V tom případě ale nemůžete spouštět aplikaci na počítači uživatele. Nebo-li tu aplikaci nebude moci nijak používat. Třeba i webová stránka jsou serializovaná data uživatele. Je potřeba rozlišovat mezi obecným termínem serializace, a standardní Java serializací založenou na rozhraních java.io.Seria­lizable a java.io.Exter­nalizable. Podobnou chybu samozřejmě mohou mít i jiné způsoby serializace, ale serializace do webových stránek a formulářů takovouhle chybu nemá.

    Problém ve skutečnosti není v tom, že jsou serializovaná data u uživatele, ale v tom, co se s nimi při deserializaci provádí. Pokud deserializujete jenom hodnoty datových entit, problém v tom není a musíte na serveru hlídat akorát to, že je datový typ správný, má správný rozsah a případně splňuje další požadavky (rozsah hodnot apod.). Problém je, že při standardní Java serializaci se serializuje i jméno třídy, takže útočník může podstrčit instanci jiné třídy se stejným rozhraním, která je k dispozici na classpath, a pokud se pak provede na té deserializované instanci kód, provede se na té neočekávané třídě (tedy pořád je to kód, který je na serveru, nemůže si útočník podstrčit svůj – ale může to být kód, který v daném kontetxu nikdy neměl být volán). Další možnost je, že by se serializovaná data načítala přímo jako bajtkód, ale to snad nikdo soudný neudělá (už jenom proto, že vnutit do JVM přímo z aplikace svůj bajtkód není úplně triviální, a pokud to někdo dělá, tak snad ví, co dělá).

  • 9. 11. 2015 13:35

    L. (neregistrovaný) 193.165.169.---

    Pokud jsou data z webového formuláře zpracovávána standardní Javovou deserializací, tak to JE chyba návrhu. Mimo jiné už proto, že se mu těžko povede něco deserializova­telného zadat :D

  • 10. 11. 2015 3:16

    sj (neregistrovaný) 94.230.156.---

    Třeba cookies? Občas v cookies jsou serializované celé třídy. Takže běžně uživatel to nemusí zadávat, ale útočník může.

    Tady sice diskuze není tak příšerná jako na slashdotu s jejich rezolutním "to nejde", ale stejně je smutné o kolik lepší by i tady mohla být diskuze kdyby každý přečetl alespoň článek a pak třeba i z něj linkovanou slideshow Marshalling Pickles kde se právě o serializavi v cookiech (ať už z Jávy, PHP, Ruby či čeho) mluví.

    A to že tu někdo říká že to je špatný návrh když někdy používá serializavi na komunikaci je możná sice pravda, ale přesto ten problém nelze ignorovat (ve stylu " kdo to napsal tak blbě tak si to zaslouží a uživatelé tak blbě napsaných aplikací taky). Navíc množství reálných aplikací které komunikují např. přes RPC a posílají si serializovaná data, případně tak mají vytvořen formát pro ukládání dat na disk apod. prostě není malé.

  • 10. 11. 2015 9:22

    L. (neregistrovaný) 193.165.169.---

    Trvám na tom, že pokud někdo ukládá java-serializované objekty do cookies, tak je to broken by design. Už proto, že se tato data musí posílat s každým requestem.

    Aplikaci, která ukládala data na disk Java serializací jsem psal, ale tam uživatel četl pouze jím vytvořená data.

    Popravdě, detaily Java deserializace jsem se nikdy nezabýval, ale tak nějak intuitivně jsem vždycky bral, že to není moc bezpečné a dá se s tím napáchat pěkná paseka.