Co chvíli je hlášena bezpečnostní díra na dalším významném webu (Alza, Mapy.cz, BontonLand). Nebo je díry zneužito. Zkuste si vyhledat slova XSS zranitelnost a pochopíte, proč je Cross Site Scripting (XSS) dnes jednou z nejrozšířenějších a nejnebezpečnějších děr.
Záležitost nepříjemná pro provozovatele webů a snad ještě víc pro dodavatele. Může poškodit jméno, může dojít na pokuty, žaloby, nebo jen pokazí vztah s klientem. Jak se proti XSS bránit? Tzv. escapováním řetězců. Bohužel naprostá většina odborníků v tom plave. (Nechci být netaktní a někoho se dotknout, snad jen řeknu, že z „československých IT celebrit“ znám asi jen jednoho člověka, který se ve věci do hloubky vyzná.) Tudíž i články o této problematice na známých webech jsou, řekněme, nepřesné.
Navíc ono escapování se obvykle provádí v šabloně, padá tak na bedra kodéra. Tedy nejkritičtější místo vyžadující vysokou erudici řeší člověk nepovolaný. Jak taková věc může dopadnout? To přece víme – viz první odstavec.
Spasí vás Nette Framework
Rád bych vám představil jednu killer feature šablonovacího systému Latte v Nette Framework. Vlastnost tak zásadní, že sama o sobě je důvodem framework zvolit. Nebo klidně z něj použít jen šablony.
- čím jste větší firma, tím je pro vás vlastnost důležitější
- žádný konkurenční framework ji dodnes nemá 1)
Nette Framework v šablonách escapuje automaticky. Jeho vlastnost Context-aware escaping rozezná, ve které části dokumentu se nacházíte a podle toho zvolí správné escapování.
Teď zabrousím do techničtější roviny. Jak to funguje, nejlépe uvidíte
na příkladu. Mějme proměnnou $var
a tuto šablonu:
<p onclick="alert({$var})">{$var}</p>
<script>
document.title = {$var};
</script>
Zápis {$var}
znamená vypsání proměnné. Jenže každé
vypsání je nutné ještě explicitně ošetřit, dokonce na každém místě
jinak. Kodér musí (například ve Smarty) připsat příslušné
modifikátory, nesmí se přitom splést a hlavně nic opomenout.
V Nette Framework není potřeba nic ošetřovat. Vše se udělá automaticky, správně a důsledně!
Pokud dosadíme do proměnné $var = 'Šířka 1/2"'
, framework
vygeneruje HTML kód:
<p onclick="alert("Šířka 1\/2\"")">Šířka 1/2"</p>
<script>
document.title = "Šířka 1\/2\"";
</script>
Samozřejmě je myšleno i na situaci, když je potřeba vypsat proměnnou
bez ošetření, například proto, že obsahuje text článku včetně HTML
značek. V takovém případě se použije zápis
{$var|noescape}
.
Konec technické odbočky. Díky Latte najednou platí, že
- podoba šablony zůstala jednoduchá
- vy se nemusíte bát, že kodér někde něco opomene
- a zároveň v něm nepotřebujete mít top odborníka na escapování ;)
- práce jde mnohem snáze
Další informace o chytrých šablonách Latte najdete v dokumentaci.
1) asi půl roku po Nette přišel s podobnou vlastností Google pro svoji knihovnu v C++, žádný framework v PHP, Ruby nebo Pythonu nic podobného, pokud vím, dosud nemá
Komentáře
Filosof #1
>> Now zabrousím to technical levels.
Google ti úplně nezvládá překlady, které nejsou správně česky 🙂
Jakub #2
V případě googlu myslíš ctemplate?
Aleš Roubíček #3
Ahoj, šablonovací systém Spark (pro ASP.NET MVC a Monorail) tohle má. V dokumentaci to ještě neni aktualizováno (ačkoli je to featura několik měsíců stará). Ale výraz
${variable}
je automaticky escapován. Nejsem si jistý, zda funguje sensitivně na kontext, kde zrovna je…vlko #4
Problem s escapovanim je v pripade ak chceme aby uzivatel zadaval html text, v php to je jednoduche staci pouzit nejaku existujucu kniznicu ako napr:
https://sourceforge.net/projects/kses/
Ale pokial ide o zdroje k problematike, tak zopar light informacii pre asp.net k problematike xss je mozne najst napr tu:
https://web.archive.org/…-100533.aspx
#stary-odkaz-#stary-odkaz-http://www.aspnet.sk/Ako-sa-branit-XSS-v-Asp.Net-100152.aspx
a v pripadne alternativa ku kses
https://web.archive.org/…-100481.aspx
BTW: Dufam, ze tychto prispevkov tu nebude moc, pretoze z ff3.5 sa mi komentar pridat nepodarilo:(
Augi #5
IMHO je třeba, aby reagoval na kontext, protože encodování znaků je jiné v hodnotách atributů a jiné v textu…
David Grudl #6
#2 Jakub, jj, tak se to jmenuje
#3 Aleš Roubíček, právě ta kontextová citlivost je na tom nejdůležitější. Můžeš to nějak vyzkoušet, jestli to umí?
#4 vlko, ano. V PHP lze takto použít třeba Texy, pravda je, že tato jeho stránka není příliš známá.
Aleš Roubíček #7
#6 David Grudl, Texy používám jako XSS filter velmi rád :)
Jakub Vrána #8
Díky, že sis na mě vzpomněl 🙂. A teď jsem za nafounkánka já… Tedy pokud jsi nemyslel sebe!
Aleš Roubíček #9
#6 David Grudl, Vypadá to na kotextovou necitlivost, navrhnu to jako možnost vylepšení;
vlko #10
#6 David Grudl, teda neviem ako presne funguje texy, ale kses odstrani z existujuceho html kodu, nepovolene znaky a atributy (na vstupe sa definuje zoznam povolenych tagov a ich atributov, ak nie je ziaden odstrani vsetky html tagy).
Roman #11
#8 Jakub Vrána, Alebo myslel Synopsiho (ehmo) 😉
mila #12
http://docs.djangoproject.com/…s/templates/#id2 (od listopadu 07)
David Grudl #13
#12 mila, žádný náznak kontextově sensitivního escapování tam nevidím (červenec 09)
mila #14
#13 David Grudl, myšleno, že je escapovaní je automatické
Wii #15
Velice se mi osvědčil jednoduchý skriptík který prochází celé pole $_POST a $_GET a likviduje veškerý html kód. Nemusím se později starat o data co mi jdou od uživatele.
Co říkáte na tohle řešení ? Ano vím měl bych spíš řešit v šabloně, ale teoreticky i prakticky se nemá jak dostat škodlivý kód do DB, kromě toho že by se tam vložil skrze DB a to už je stejně pozdě 🙂
David Grudl #16
#15 Wii, To není dobré řešení – protože provádíš výstupní filtrování na vstupních datech. V takové aplikaci pak není možné mít třeba editor HTML článků, protože už vstupní filtr je poškodí. Poškodí i vše, co jen jako HTML vypadá, ale není (např hypotetický nick
John <Wii> Doe
). Naopak nechá proklouznout kontrolní znaky a nevalidní UTF-8 řetězce.Wii #17
#16 David Grudl, toho jsem si vědom, že nepropustí žádný html editor a proto jsou v cfg aplikaci nastavený názvy prvků, který nemá kontrolovat.
Špatně jsem se vyjádřil, nelikviduje html kód ale tvoří entity, takže bude výsledek
John <Wii> Doe
, což se zobrazí korektně.„kontrolní znaky a nevalidní UTF-8 řetězce“ co si prosím pod tím mám představit ?
David Grudl #18
#17 Wii, tvoření entit je stejný problém – filtr, který má fungovat na výstupu, aplikuješ na vstup. S takovým řetězcem už nemůžeš nic dělat, nelze ho například oříznout na potřebnou délku apod.
Prťka #19
Jak to vypadá s tím článkem o nových šablonách?
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.