Bezpečnostní opatření Admineru
Školení, která pořádám
Hlavní prioritou při vývoji Admineru je bezpečnost. Jaká konkrétní opatření jsou tedy zavedena?
- XSS
- Pokud by se u vypisovaných dat interpretoval HTML kód, mohlo by to mít na bezpečnost fatální následky. Všechna data se proto ošetřují funkcí htmlspecialchars. Binární data se posílají s hlavičkou
Content-Disposition: attachment
, takže se v nich HTML kód také neinterpretuje. Vývojová verze Admineru také posílá hlavičku X-XSS-Protection: 0
jako obranu před modifikací stránky v IE8 a bezpečnostními problémy ve starších vydáních tohoto prohlížeče.
- CSRF
- Kupodivu jde o jednu z nejdůležitějších obran. Pokud by uživatel přihlášený do Admineru přišel na stránky záškodníka, tak by mohl bez svého vědomí provádět operace, které si útočník přeje. Provedení všech operací je proto zabezpečeno tokenem a to včetně odhlášení.
- ClickJacking
- Pokud by si cizí stránka zobrazila Adminer v rámu, mohla by uživatele nalákat, aby prováděl operace podle pokynů útočníka. Adminer proto posílá hlavičku
X-Frame-Options: deny
, která zobrazení v rámu zakáže.
- Session Fixation
- Po přihlášení se volá funkce session_regenerate_id.
- Session Hijacking
- Session identifikátor se pokud možno přenáší v cookie a jen pokud je má uživatel zakázané, tak se přenese v URL. Ani tak ale nemá prakticky příležitost uniknout.
- HTTP response splitting
- V obsahu hlaviček se nikdy neposílá znak konce řádku. Od PHP 4.4.2 a 5.1.2 se o to stará samo PHP, ale Adminer podporuje i starší verze.
- Cookies
- Všechny cookies se posílají s příznakem
httponly
(od PHP 5.2.0) a pod HTTPS jen zabezpečeně. To je pojistka před XSS.
- E-mail injection
- Při odesílání e-mailů z Adminer Editoru hlavičky nesmí obsahovat znak konce řádku.
- Roboti
- Všechny stránky se posílají s hlavičkou
<meta name="robots" content="noindex">
. To je důležité proto, aby se Adminer zbytečně nezobrazoval ve výsledcích vyhledávání. Vstup by měl být samozřejmě i tak zabezpečen dost silným heslem. Adresu Admineru není naopak vhodné dávat do souboru robots.txt
, protože by to naopak mohlo nalákat zvědavce.
- Odkazy
- Externí odkazy se navštěvují pomocí přesměrování na veřejné stránce. Tím se cílová stránka nedozví adresu Admineru, což je důležité jednak při přenášení session identifikátoru v URL a jednak kvůli zvědavcům. Při HTTPS se adresa nepřenáší, takže tento mechanismus není třeba.
- Podstrčení proměnných
- Všechny proměnné se před použitím inicializují, což je důležité proto, že Adminer může být vložen do jiného skriptu a také může být spuštěn s nastavením
register_globals
. Nepoužívá se pole $_REQUEST
, protože může obsahovat cookies nastavené jinou aplikací na stejné doméně. Adminer používá vlastní session identifikátor, aby nedocházelo ke kolizi dat s jinými aplikacemi.
- SQL Injection
- Obrana proti SQL Injection kupodivu není v Admineru bezpečnostní opatření, protože jakýkoliv příkaz může uživatel vykonat pomocí ručního zadání SQL. V tomto případě jde tedy čistě o správnou funkčnost aplikace. Obrana spočívá ve vypnutí
magic_quotes_gpc
a následném použití mysql_real_escape_string nebo obdobné funkce.
- Hesla
- Trvalá hesla se před uložením do cookie zašifrují pomocí klíče (ve výchozím nastavení je náhodně vygenerovaný).
- Kódování
- Stránka se posílá v kódování UTF-8 a data se před vypsáním ověřují. Použití neplatného znaku by mohlo způsobit nezobrazení stránky v XHTML, stránka se ale stejně posílá jako HTML.
- Vzdálené spuštění
- Adminer nevkládá cizí soubory ani nevyhodnocuje kód a nespouští programy.
I pečlivě zabezpečená aplikace správně poběží pouze v dobře nastaveném prostředí. Jaké jsou tedy nároky na správce a uživatele?
Zodpovědnost správce serveru
- Nastavit úložiště session dat tak, aby k nim neměli přístup ostatní uživatelé serveru. Jinak si mohou přečíst heslo k databázi, které se do session ukládá.
- Nastavit
upload_tmp_dir
tak, aby do něj neměli přístup ostatní uživatelé serveru. Jinak si mohou přečíst výchozí klíč pro šifrování hesel ukládaných do cookie (a nahrávané soubory).
- Použít alespoň PHP 5.2.3 (podporuje mysql_set_charset) nebo mít v MySQL jako výchozí nastavené jednobajtové kódování nebo UTF-8. Jinak může dojít k SQL Injection.
- Pokud možno používat HTTPS. Jinak může heslo a data po cestě někdo odposlechnout a případně i změnit.
- Lepší je vypnout
session.auto_start
. Jinak hrozí kolize se session proměnnými jiných aplikací.
Zodpovědnost uživatele
- Používat dostatečně silné přístupové heslo nebo nemít stránku dostupnou zvenku.
- Neukazovat nikomu vytištěné stránky, pokud obsahují URL se session identifikátorem.
- Nedávat nikomu uložený HTML kód jakékoliv stránky Admineru (obsahuje CSRF token) nebo při platném přihlášení do Admineru nechodit na jiné stránky.
- Používat IE >= 8, Chrome >= 2, Firefox
s extenzí NoScript >= 3.6.9 jiný prohlížeč podporující hlavičku X-Frame-Options
nebo při platném přihlášení do Admineru nechodit na jiné stránky.
- Nemít v souborovém systému přístupné databáze SQLite s citlivými údaji a nemít právo zápisu do nežádoucích adresářů, nebo si vytvořit přizpůsobení s vlastní metodou
login
(platí i v případě nastavených výchozích přihlašovacích údajů pro MySQL), nebo používat verzi pouze pro MySQL.
Přijďte si o tomto tématu popovídat na školení Bezpečnost PHP aplikací.
Diskuse
v6ak:
Do zodpovědnosti správce serveru bych ještě přidal ona opatření k SQLite, popř. jiným databázím v případě default password nebo zabezpečení založené na IP.
Martin:
Jen štiplavý dotaz k položce Odkazy. Vzhledem k tomu, že všechny odkazy jdou přes tvůj server, je také velmi jednoduché jejich odchytávání a ukládání (z jakéhokoliv důvodu) ze tvé strany. Ukládáš si někam takto přesměrované odkazy, nebo je jejich průchod čisté přesměrování a ty s k tomu, co přes přesměrovací službu jde, nedostaneš?
Jakub Vrána :
Na serveru je standardní Apache log, ten ale nesleduji. Jinam se odkazy neukládají. Žádná externí sledovací služba na přesměrovávací stránce pochopitelně není. Ona je cenná hlavně adresa, kde běží Adminer, ani ne tak ta cílová. A ta se v hlavičce Referer posílá i při zjišťování nové verze a externím zvýrazňování syntaxe.
Obrana proti tomu je triviální – používat HTTPS, kde se Referer nepřenáší, což Adminer respektuje (pod HTTPS jdou odkazy přímo na cílovou stránku bez přesměrování). Alternativně na firewallu zakázat posílání hlavičky Referer nebo ve Firefoxu pomocí volby network.http.sendRefererHeader. Ale nejlepší je fakt to HTTPS (klidně se self-signed certifikátem).
Martin:
Díky. Zajímalo mě právě to, zda nějakým způsobem sleduješ, kde je adminer nainstalovaný a co se na něm dělá. Jako správně paranoidního admina mě trochu děsilo, že by někdo tyto informace sbíral.
Tomáš Fejfar:
Tak logicky, i kdyby to Kuba dělal, tak to ti to neřekne... :))
Stanislav:
Ono i kolik lidí by si všimlo, že Jakub přidal jeden řádek s mail() k přihlášení do zkomprimované verze...
Prostě Jakubovi věřím
Diskuse je zrušena z důvodu spamu.