Jak psát kód: Data před použitím ošetřete

Školení, která pořádám

Jde o jednoduché pravidlo, které zabrání většině nejběžnějších bezpečnostních problémů: Respektujte kontext, ve kterém používáte data a ošetřete znaky, které mají v daném kontextu speciální význam.

Problém s tímto pravidlem je, že se na něj dá snadno zapomenout. Je mnohem jednodušší napsat echo $_GET["message"] než echo htmlspecialchars($_GET["message"]) nebo $pdo->query("… LIMIT $_GET[limit]") než:

<?php
$stmt = $pdo->prepare("… LIMIT :limit");
$stmt->bindValue('limit', $_GET["limit"], PDO::PARAM_INT);
$stmt->execute();
?>

Správné řešení je použít abstrakci, která vám nedovolí udělat chybu. Např. v Nette Latte to znamená zakázat vkládání PHP kódu značkou <?php ?> a neošetřeného HTML značkou {!$}. U databázové abstrakce to může znamenat kontrolu toho, že se na místě dotazu používá výhradně konstantní řetězec pomocí statické analýzy.

Je důležité si uvědomit, že správné ošetřování dat neřeší jen bezpečností problémy, ale i problémy s použitelností. Narazíte na ně v situaci, kdy někdo vaší aplikaci pošle název McDonald's nebo <1337>. Důležité je proto toto pravidlo nepodcenit ani v situacích, kdy na bezpečnosti zdánlivě nezáleží, třeba v Intranetové aplikaci (i když tam na bezpečnosti záleží přesně stejně jako u veřejné aplikace).

Přijďte si o tomto tématu popovídat na školení Bezpečnost PHP aplikací.

Jakub Vrána, Dobře míněné rady, 31.5.2013, diskuse: 7 (nové: 0)

Diskuse

Michal Raška:

Jakube, jak vyřešit případ, kdy potřebuji vložit HTML kod do šablony pokud nepoužiji {!$..}? Jde například o uživatelské formátovaní, které není předem známé.

tbx:

Muzes pouzit http://texy.info/ nebo nejaky vlastni parser (treba [b] namisto <b>, ...)

Lamicz:

Používám HTML Purifier

ikona Jakub Vrána OpenID:

Pokud mám nějaká prokazatelně bezpečná HTML data (např. výstup Texy), můžu je tak označit už při předávání dat do šablony. V Nette k tomu slouží Html::el(). V šabloně pak můžu použít normální {$}.

Michal:

Koukám, že tady to šlo hodně dolů - poslední dobou tu píšeš naprosto banální rady, asi jen proto, aby bylo kam vrazit reklamu na nějaká školení. Škoda, psal jsi líp.

ikona Jakub Vrána OpenID:

Dopředu jsem avizoval, že proberu několik jednodušších témat: http://php.vrana.cz/jak-psat-kod-nepouzivejte-copy-paste.php. Bohužel to jsou věci, které teď zrovna řeším. Navíc některé věci zase tak triviální nejsou – např. s http://php.vrana.cz/jak-psat-kod-udelejte-praci-najednou.php se potýká spousta aplikací a vyřešit to systematicky správně vyžaduje spoustu fištrónu.

Filip Procházka:

Myslím, že je dobře, že se tyhle články píší a že to píše autorita. Nejsou to samozřejmosti pro každého a hlavně si nemyslím, že Jakub by měl někomu obhajovat že napsal článek ;)

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.