Jak nejlépe chránit...

Pěkný den.

Zajímalo by mě, jak si nejlíp ochránit databázi před útočníky. Na internetu byly různé funkce, ale v diskusích se vždycky nějak vyvrátily. Jsem z toho trochu zmatený...

Používám pro proměnné funkce htmlspecialchars a stripslashes, pro hesla SHA1. Do SQL dotazu je prý dobré dát i mysql_real_escape_string.
Má někdo zkušenosti, jak nejlépe databázi ochránit ?

Možná by toto téma mohlo pomoci i některým ostatním uživatelům.

Děkuji za jakékoliv posty.
Tak je dobré si i položit otázku, co chceš chránit.

1) Ochrana přístupových údajů k DB
Zde je nejlepší, aby se k těmto údajům nikdo nedostal. To znamená, oddělit od kódu a umístit nejlépe mimo document_root. Pokud nemohu ovlivnit document_root, tak zajistit, aby se k němu nikdo nedostal. Nejlépe znepřístupněním adresáře nebo i samotného souboru pomoci .htaccess.
Pokud je někdo paranoidní, tak si může přístupové údaje i zašifrovat.

2) Ochrana před SQL injection
Každý vstup, každou proměnu, která obsahuje nebo vstupuje do SQL dotazu, je potřeba ošetřit. Jelikož existuji různé databáze a různé praktiky zápisu dotazů, tak neexistuje i univerzální ochrana.
V případě MySQL je však nejlepší pro ošetření vstupu používat výhradně funkci mysql_real_escape_string(). Existují i další, jako addslashes(), strip_tags(), htmlspecialchars() ale ty nezajišťují lepší ochranu.

Funkce stripslashes() je v tomhle krajně nebezpečné, dělá pravý opak.
Pokud však máš na mysli výstupy, pak jej můžeš použít. Je třeba však vědět, jaké hodnoty hodláš vypisovat a dle toho pak ošetřovat výstup.

3) Ukládání hesel
Základní pravidlo je, nikdy neukládat hesla v plain textu. Základní a nejjednodušší ochrana je použití hash funkcí - md5, sha1 apod.
Ovšem poslední dobou nemusí tyto zahashované hesla stačit. Na netu existuji databáze hashu, ze kterých lze zjistit jejich původní hodnotu.
Proto lze použít sofistikovanou ochranu v podobě saltování nebo cyklování. Salt, alias osolení, je způsob, kdy hash obsahuje kromě hesla i nějaké doplňující údaje. Třeba login. Cyklování je vícenásobné použití hashe. Třeba sha1(sha1(heslo)). Tyto praktiky zvyšují ochranu, právě před tou databázi hashe.
Jiný způsob ochrany je použití šifrovacích algoritmů. Tento má spíše smysl, pokud chceš zpětně zjistit heslo nebo jakýkoli zašifrovaný údaj.
Doplním Tomíka:

1. na WZ je trochu problém umístit soubor s hesly mimo document_root, ale dá se uložit třeba do .htmysql . Apache takový soubor nezobrazí, ale dá se includovat. Je to jen mírné zvýšení bezpečnosti. Ve chvíli, kdy připustíš upload nějakého souboru.php , je taková ochrana k ničemu.

3. Hashovací funkce sice nejsou neprolomitelné, ale na projekty na WZ IMHO plně vyhovují. Pokud však někdo použije slabé heslo, tak mu ani sůl nepomůže. Zpětné zjišťování hesla nemá smysl, proto se u nich zásadně používají hashe jako nejlepší známá ochrana. I před administrátory.

Na WZ není HTTPS. V tom případě je zbytečné se zabývat bezpečností MD5 či SHA-1. Pro potřebný účel jsou víc než vyhovující. Podstatné je ošetřit PHP injection (include() příspěvků do diskuzí) a SQL injection (přidávání neošetřených částí vstupních řetězců do SQL dotazů).
Děkuji za rady. Měl jsem na mysli SQL injection při odeslání formulářů.

Narazil jsem na vysvětlení, že když je magic_quotes_gpc vypnuta, pak se stripslashes() nemá zadávat. Naopak mysql_real_escape_string je dobré použít.

V tom případě bych se ještě chtěl zeptat, zda mohu zapsat třeba takto:

if (isset($_POST['prom']))
{
$prom = $_POST['prom'];
$prom = htmlspecialchars($prom);
$prom = mysql_real_escape_string($prom);

mysql_query("UPDATE databaze SET tabulka = '".$prom."' WHERE ...");
}
Direktiva magic_quotes_gpc způsobuje to, že automaticky již escapuje vstup. Tedy za tebe aplikuje funkci addslashes() na všechny superglobální proměnné.
Ovšem toto je nežádoucí efekt. Proto je od PHP 5.3 zavržen. A většina zkušených programátorů se ho snaží vypínat nebo potlačit.

Pokud jde o tvůj příklad, tak htmlspecialchars() bych raději neaplikoval a nechal ho až na samotný výstup.
Jedno doporučení pro práci s databázi je ukládat čistá data. Je to dáno tím, abys mohl případně tato data snadno upravit i jinde. Třeba v phpMyAdminu nebo v jiném frontendu.