Závažná bezpečnostní chyba ve Springu odhalena!

Otázka: Je pravda, že v Košicích upálily rusa?
Odpověd rádia Jerevan: Ano, je to pravda, ale nebylo to v Košicích, ale v Kostnici a nebyl to rus, ale Hus.

Myslel jsem si, že jsem expert na senzační titulky. Ale tento je nepřekonatelný. Mohli jste na něj narazit dnes, například na theserverside.com. Na první pohled to vypadá, že našli závažnou bezpečnostní chybu ve Springu. Na druhý pohled člověk přijde na to, že Rádio Jerevan obnovilo vysílání.
Takže, je pravda, že je ve Springu bezpečnostní chyba? Ano je to pravda, jenom to není ve Springu, ale ve Spring MVC a není to chyba, ale vlastnost.
Jde o to, že Spring MVC napojuje (binduje) hodnoty v HTML formulářích na beany. Pokud mám ve formuláři políčko se jménem name a v beaně pole se stejným jménem, Spring MVC mi automaticky nastaví hodnotu v beaně podle hodnoty ve formuláři. A to je ta chyba. Může se totiž stát, že mám v beaně jinou sadu polí než v HTML formuláři. Útočník teoreticky může v dotazu poslat hodnotu pole, které nebylo ve formuláři, a které tudíž ani nečekám. Prostě a jednoduše mi pošle jeden parametr dotazu (request parameter) navíc. Pokud správně trefí jméno, Spring nastaví hodnotu pole beany, u kterého to neočekávám. Takže teoreticky může změnit něco, co nechci aby se měnilo. To je závažná věc, a je dobré ji mít na paměti. Rozhodně bych to nechtěl zlehčovat. Musím se přiznat, že mi to až dodnes nedošlo.
Nicméně pokud to trochu přeformuluji, tak z toho plyne, že nemáme věřit ničemu, co nám přichází od uživatele. To rozhodně není žádná novinka. Jenom na to často zapomínáme. Uvedený problém má ve Spring MVC jednoduché řešení. Prostě mu řekneme, jaká pole má napojovat.
Samozřejmě to není jenom problém Spring MVC, stejný problém budou mít všechny podobně fungující frameworky (možná kromě JSF). Když mi přijde HTTP dotaz, tak nevím, která políčka byla v HTML formuláři. On tam konec konců ani žádný HTML formulář být nemusel. Dotaz mohl být klidně vygenerovaný nějakou aplikací. Jediné co mohu udělat, je explicitně určit, která pole se mají nastavovat. To Spring MVC umožňuje, jenom to skoro nikdo nepoužívá.
Takže abych to shrnul. Ve Springu bezpečnostní chyba není (alespoň co je mi známo). Chyba ale může vzniknout při jeho neopatrném používání. Doufám že se zítra nedočtu, že je závažná chyba v Oraclu. Doslechl jsem se, že umožňuje zavolat DROP SCHEMA a to může mít závažné následky na integritu dat.

Paralelní svět

V poslední době se hodně mluví o Erlangu. No a protože jsem slaměný vdovec a u žehlení se nudím, pustil jsem si přednášku od otce Erlangu Joe Armstronga. V tomto zápisku se chci o své dojmy z této přednášky podělit s vámi, mými oddanými fanoušky. Chci předem upozornit, že to jsou jen dojmy, pořádně ještě nemám na věc ujasněný názor.
Začátek přednášky je relativně zajímavý. Už jsem nejméně stokrát slyšel, že se programátoři musí začít chovat jinak, protože se objevily vícejádrové procesory. Ale vždy jsem si říkal, že tu máme přeci víceprocesorové stroje už hodně dlouho, tak jakápak změna. Až díky této přednášce jsem mi došlo, že změna není v tom, že máme více jader. Změna je v tom, že se sekvenční zpracování procesorů nezrychluje tak, jak jsme byli zvyklí. Od jisté doby roste rychlost hlavně díky paralelizaci. Všimněte si, že taktovací frekvence procesorů se v poslední době zas tak zásadně nemění. Naopak se objevují X jádrové procesory. Už prý existuje 1000 jádrový procesor, pokud bude růst počet jader exponenciálně, můžeme se v nedaleké budoucnosti dostat na zajímavá čísla. Předpokládejme, že je takový nárůst počtu jader možný. Dosud jsme byly zvyklí, že naše programy automaticky s novým procesorem zrychlí. Od příště už to tak být nemusí. To že klient můj sekvenční program nasadí na procesor s miliónem jader, neznamená, že bude milionkrát rychlejší. Spíš bude pomalejší než na jednojádrovém.
Tak a teď mé dojmy. Jak to ovlivňuje programátory? Protože jsem zvyklý na serverovou Javu, budu psát hlavně o ní. Představme si, že máme 1000 jádrový procesor. Jak budeme muset změnit svůj kód, aby běžel efektivně? Představme si pro začátek, že mám jednoduchou aplikaci založenou na servletech. Přijde dotaz, já ho v jenom vlákně zpracuji a v tom samém vlákně pošlu odpověď. Abych si to zkomplikoval, budu předpokládat, že ne všechna práce je výpočetně náročná, občas budu čekat na disk, databázi na jiném stroji atp. To znamená, že potřebuji mít víc vláken než procesorů (jader), abych byl schopen je vytížit. To znamená, že potřebuji víc než tisíc současných požadavků, aby ta vlákna měla co dělat (tady to trochu moc zjednodušuji, ale snad mi to prominete). Pokud je tento předpoklad splněn, nemusím svoji aplikaci měnit vůbec. Tedy za předpokladu, že JVM zvládne 1000 jádrový procesor.
Pokud mám méně než několik tisíc současných dotazů, procesor plně nevyužiji. Musím práci rozsekat na víc kousků. Jde to v Javě vůbec? Pan Armstrong tvrdí, že ne. Tvrdí, že Java je staromódní jazyk, který se spoléhá na sdílenou paměť, sdílený stav, zámky, transakce a podobná zvěrstva. Naproti tomu je Erlang moderní jazyk, který je navržen s tím, aby skvěle fungoval paralelně, který nemá problém s miliónem běžících pidiprocesů, které žádný stav nesdílejí, jenom si předávají zprávy. Tvrdí navíc, že problém Javy a podobných jazyků je přímo v jejich pojetí. Že jsou to jazyky sekvenční, kdežto Erlang je jazyk paralelní. Tvrdí navíc, že svět jako takový, je paralelní, tudíž je těžké ho popsat sekvenčním jazykem. Abych pravdu řekl, nevím jestli je svět paralelní nebo sekvenční. Na jednu stranu se každý člověk stará sám o sebe a rozhodně nesdílí svůj stav s ostatními. Jenom jim posílá všelijaké zprávy. To by nahrávalo paralelnímu pohledu. Jen ovšem do té doby, než se octnete v dopravní zácpě, která je podle mě silně sekvenční.
A v tom je právě zakopaný pes. Potíž není v jazyku, ale v řešeném problému. V Javě také nemusím sdílet žádný stav. Každé vlákno může mít svoji logicky oddělenou paměť. Když se nad tím zamyslím, tak už se to dávno děje. Proto jsou tak populární řešení založená na JMS. Jednotlivé oddělené procesy si jenom předávají zprávy. To je přesně to, co mi poskytuje Erlang. V Javě to jenom není zakomponováno přímo v jazyku. Je to v ní na logicky vyšší úrovni. A tedy i s mnohem vyšší režií.
Ano je to tak, pokud mám problém, který se dá rozseknout na hodně malých úkolů, je snadné ho paralelizovat. Ale na to není nutné měnit jazyk. Mohu použít JMS, JINI nebo jiné jednodušší mechanizmy. Stále tu ale ještě máme spoustu aplikací, které prostě vyžadují sdílený stav, jejichž doména je sekvenční, které se paralelizovat nedají. Jsem rád, že mohu používat jazyk, který mi to umožňuje.
Bylo by samozřejmě pěkné, kdyby Java umožňovala snazší spouštění paralelních úloh. Na druhou stranu k tomu už spěje. V Javě 5 byly zavedeny executory (spouštěče?), Futures a datové struktury, které nevyžadují synchronizaci. Možná není paralelní programování v Javě tak přímočaré jako v Erlangu, ale relativně jednoduché je. Takže můj závěr je následující – pokud máte problém, který je principiálně podobný telefonní ústředně, zkuste Erlang. Pokud píšete obecnou aplikaci, zůstaňte u Javy.

Kterak být agilní ve vodopádu

Jak máme prodat agilní vývoj managementu? Nedělejte to, oni beztak nevědí co děláte.

Onehdá jsme s takovou podivnou partou lidí v hospodě řešili, jak propagovat Agilní vývoj v jedné nejmenované firmě. Potíž je v tom, že v té firmě se vyvíjí vodopádem. (I když management tvrdí, že se tam dělá RUP.)

No a včera jsem na InfoQ narazil na zajímavou přednášku o tom, jak dělat Agilní vývoj ve vodopádu. Takže pokud vás toto téma zajímá, najděte si hodinku a čtvrt a podívejte se na to. Nedovíte se tam nic převratného, ale alespoň to naznačí, kudy by se dalo jít.