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:

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. 2008Ctemplate zavádí auto-escape
11. 12. 2008Nette zavádí content sensitive escaping
31. 3. 2009Google veřejně píše o Automatic Context-Aware Escaping
7. 4. 2009Nette 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.

Jakub Vrána, Seznámení s oblastí, 20.7.2009, diskuse: 14 (nové: 0)

Diskuse

ikona v6ak:

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.

ikona Jakub Vrána OpenID:

$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.

ikona v6ak:

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.

ikona Jakub Vrána OpenID:

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...

ikona Jakub Vrána OpenID:

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.

ikona Jakub Vrána OpenID:

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

ikona Jakub Vrána OpenID:

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.

ikona David Grudl:

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

ikona Jakub Vrána OpenID:

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.

ikona David Grudl:

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).

ikona Jakub Vrána OpenID:

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.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.