Osobní stránky

Použití příkazu grep pro hledání bezpečnostních chyb ve zdrojovém kódu

Jednou z největších výhod operačních systémů, postavených nad linuxem je bezesporu příkazový řádek, neboli terminál. Někdy se nazývá i konzole. Pomocí příkazů zabudovaných do terminálu lze ovládat celý operační systém bez nutnosti používat myš. Nejvíce se příkazový řádek používal v dobách, kdy počítače nepoužívaly žádné grafické rozhraní a všechny informace se zobrazovaly pouze textově. Síla a flexibilita terminálu ale přetrvává dodnes.

Jedním z nejpoužívanějších příkazů v terminálu je grep. Slouží k vyhledávání a filtrování informací. Nejčastěji se používá v kombinaci s dalšími příkazy. Například pomocí příkazu: ps aux | grep jmeno-procesu lze vyfiltrovat běžící procesy podle jména.

Základní použití příkazu je: grep hledany-text. Pokud chceme v hledaném textu používat speciální znaky, jako například mezery, tak je potřeba tento text vložit do uvozovek (" nebo '). Za celý příkaz lze umístit seznam souborů, v kterých se má text hledat. Příklad:

grep "echo phpinfo();" index.php index2.php

Příkaz grep má různé přepínače, pomocí kterých lze ovlivnit chování. Například přepínač -i (--ignore-case) bude ignorovat velikost písmen. Přepínač -R, -r nebo --recursive prohledává rekurzivně všechny podadresáře.  Zkombinováním těchto příkazů lze prohledat všechny PHP soubory, zda neobsahují parametr $_GET. Příkaz:

grep -i -r "\$_GET" *.php

Vyhledávaný parametr lze měnit, jediné na co je potřeba myslet je, že speciální znaky jako $, ', " a podobné je nutné uvést s lomítkem. Vše funguje stejně jako v jazyce PHP .

V některých případech bychom chtěli, filtrovat pomocí více parametrů, které nemusí být hned vedle sebe. K tomuto účelu lze použít grep dvakrát. Řekněme, že chceme najít řádky, které obsahují $_GET a zároveň i echo. Tyto řádky lze vyfiltrovat příkazem:

grep -i -r "\$_GET" * | grep "echo"

V předchozím případě jsme použili druhý grep pro filtrování výsledků prvního grepu. Celkem pěkné řešení, ne?

Někdy ale při prohledávání celého projektu narazíme na problém se soubory z verzovacích systémů. Tyto soubory jsou uloženy ve složkách .git, .svn a podobně. Pokud tedy hledáme v celém projektu, příkaz grep prohledává i tyto složky. Tento problém lze ale celkem jednoduše vyřešit vynecháním těchto složek. K tomuto účelu slouží příkaz --exclude-dir=adresar. Jako parametr lze zadat i více adresářů.

Příklad:

grep -i -r --exclude-dir={.svn,.git} "\$_GET" * | grep "echo"

Jak je vidět, příkaz grep je velmi mocný. Pomocí kombinace různých přepínačů lze vyhledávat v celém projektu podle různých parametrů. Tato možnost se hodí především na serveru, kde nelze používat vývojové nástroje a nezbývá nám nic jiného, než použít k vyhledáváná terminál.

Pomocí příkazu grep je výhodné hledat především bezpečnostní nedostatky. Podle žebříčku 10 nejčastějších zranitelností OWASP (The Open Web Application Security Project) je nejdůležitější se zaměřit na SQL injection, přihlašování a práce se session a XSS (Cross site scripting). Jako obrana před těmito zranitelnostmi je potřeba ošetřovat vstupní parametry a správně je interpretovat.

Důležité je tedy otestovat, zda nejsou někde v aplikaci vypisovány vstupní parametry od uživatele bez ošetření (echo v kombinaci s $_GET, $_POST, $_COOKIE), anebo zda jsou vstupní proměnné ošetřovány při vkládání do databáze (mysql_query, mysqli_query, PDO::query v kombinaci s $_GET, $_POST, $_COOKIE). Někdy je také důležité dbát na správné ošetření parametrů proměnné $_SERVER a podobných, které může uživatel ovlivnit. Mimo kontrolu vstupních parametrů lze hledat v kódu i potenciálně nebezpečné funkce jako exec() nebo shell_exec().

Vše záleží na vaší aplikaci a použitých knihovnách. Pomocí funkce grep lze rychle otestovat i cizí knihovny na potenciálně nebezpečný kód, bez dlouhého zkoumání zdrojových souborů v editoru. Každá aplikace může mít slabiny jinde a je proto potřeba dbát na bezpečnost neustále.

Jakub Škvára


Jakub je cestovatel, blogger a webový vývojář. Zajímá se především o technické novinky a rád navštěvuje konference. Používá: Symfony2 Framework, AngularJS, NodeJS, MongoDB a další moderní technologie. Aktuálně žije v Londýně.