Kontextově citlivé ošetřování výstupu
Školení, která pořádám
Představte si takovouto šablonu:
<script type="text/javascript">
var userId = {$userId};
</script>
<p style="color: {$color};" title="{$title}">
<a href="" onclick="return !confirm({$message});">{$desc}</a>
</p>
<!-- Executed in: {$time} s -->
A teď si představte, že takovou šablonu dostane do ruky HTML kodér a má všechna data správně ošetřit. Vsadím se, že na něco zapomene nebo v tom udělá jinou chybu. Proto jsem rád, že CurlyBracketsFilter v Nette všechna data ošetří správně a že jsem k tomu svým malým dílem také mohl přispět. Rozlišují se tyto kontexty:
- HTML text
- Hodnota HTML atributu (uzavřená do uvozovek nebo apostrofů)
- Značky
<style>
a <script>
se sekcí CDATA
- HTML atributy
style
a on*
- HTML komentáře
Ostatní kontexty (jako např. vnitřek značek nebo neuzavřená hodnota atributu) zvláštním způsobem ošetřovány nejsou, protože to dost dobře nejde. Na těchto místech by se tedy uživatelská data neměla vyskytovat.
Kontextově citlivé escapování šablon provádí pokud vím už jenom Google Ctemplate, který používá velmi podobné kontexty (navíc podporuje ještě URL, které CurlyBracketsFilter řeší nezávisle).
Na závěr ještě přehledová tabulka:
27. 4. 2008 | Ctemplate zavádí auto-escape |
11. 12. 2008 | Nette zavádí content sensitive escaping |
31. 3. 2009 | Google veřejně píše o Automatic Context-Aware Escaping |
7. 4. 2009 | Nette veřejně píše o kontextově-sensitivním escapování |
Nette tedy nebyl první projekt, který danou vlastnost implementoval, ale na tom nakonec moc nezáleží. Podle všeho vznikla obě řešení nezávisle na sobě a to, že jsou si podobná, je „důkaz“ správnosti tohoto přístupu.
Diskuse
Já tam potom vidím CSS injekci, která může vést v některých prohlížečích (minimálně Firefox a IE) k XSS...
Nebo je to zde špatně popsáno.
Předpokládám možnost $color ovlivnit útočníkem.
$color v daném kontextu se ošetřuje helperem escapeHtmlCss, který ošetří speciální znaky pro CSS a potom pro HTML. Možnost XSS tam nevidím.
Aha, buď jsem přehlédl zmínku o style v "# HTML atributy style a on*" nebo's to tam dopsal. Ale tipuju to spíš na tu první variantu.
Správně :-). Úpravy článků označuji značkami <ins> a <del> a přiznávám v komentářích.
Messa:
Jen malé doplnění - kontextově citlivé escapování by měly umět přinejmenším i všechny šablonovací knihovny (enginy, chcete-li), které se šablonou nepracují jako s textem, ale jako se strukturovaným obsahem. Např. Genshi nebo Kid, ze kterého Genshi tak trochu vychází (to je pro Python, dle Google Ctemplate ale soudím, že se už nebavíme jen o PHP). Doplňte si prosím do přehledové tabulky přinejmenším rok 2006...
Kontextově citlivé escapování je něco jiného než automatické escapování. Např. Genshi data automaticky escapuje, ale kontextu si nevšímá. Např. z <a onclick="alert('$x');"> udělá <a onclick="alert(''');">, pokud $x obsahuje '.
Messa:
Řetězec "' se v Genshi escapuje jinak, pokud je uveden v atributu a jinak, pokud je v textu - to bych označil za kontextově citlivé. Jen těch kontextů rozlišuje trochu méně - čeho si nevšímá je Javascript.
Jediné kontexty, které Genshi roslišuje, je HTML text a uzavřená hodnota atributu. V těchto dvou kontextech se data dají ošetřit stejně, takže mi to jako nijak užitečná vlastnost nepřijde.
Čistě formálně vzato skutečně jde o kontextově citlivé ošetřování, ale kontextů je tak málo, že se na automatické ošetřování rozhodně nedá spolehnout.
Leos Ondra:
Ja jsem nejak natvrdly - nechapu uz zacatek, totiz co by na takove sablone mel HTML koder osetrovat? Ten tvori html, o promenne se nestara ne? Leo
HTML kodér u větších projektů obvykle dostane proměnné, které může v kódu používat. Tyto proměnné se nedají ošetřit v PHP kódu, protože nevíme, v jakém kontextu je kodér použije. O jejich ošetření se tedy musí postarat kodér nebo přímo šablonovací systém.
Nette má "veřejně" automatické escapování od 16. června 2008, tedy ode dne, kdy byl filtr CurlyBrackets umístěn na SVN http://jdem.cz/bskf8
Automatické escapování ano, to je zcela běžná věc, kterou umí třeba i Smarty. Článek je ale o escapování, které zohledňuje kontext, ve kterém se proměnná použije – podle toho zvolí ošetřovací funkci.
Spíš jsem doplňoval tu tabulku, kde je automatické escapování zmíněno (také na něm nevidím nic extra zajímavého).
Oni totiž poněkud nešťastně říkají auto-escape právě kontextově citlivému escapování. Tabulka srovnává srovnatelné, jen se to různě jmenuje.
Diskuse je zrušena z důvodu spamu.