Jak zlepšit zabezpečení čtvrtiny celého webu

Embed Size (px)

Citation preview

Michal paek www.michalspacek.com @spazef0rze

WordPress

Not WordPress

Jak zlepit zabezpeen tvrtiny celho webu.

WordPress pr pouv 27 % webu. Na nsledujcch slajdech bych chtl naznait, co bychom ve WordPressu mohli zlepit z pohledu bezpenosti,protoe kdy to udlme, tak se zv zabezpeen pomrn hodn web. J vm, ne vichni aktualizuj, ale o tom nkdy jindy. Slajdy obsahuj poznmky, kter v pvodn prezentaci nejsou.

V roce 2016 jsem na konferenci Passwords v Las Vegas spustil mini-projekt, seznam firem, kter njak zveejnily, jak ukldaj hesla svch uivatel. Chci tak veejn chvlit firmy, kter to dlaj bezpen a pokud zatm ne, tak aby zaaly.

Zpsob ukldn hesel zveejnil i Facebook, v roce 2014 o tom pednel Alec Muffett. Odkaz na pednku je samozejm uveden i v mm mini-projektu.

$thisiteration_count_log2
+ ((PHP_VERSION >= '5') ? 5 : 3;

$count = 1 iteration_count_log2 je nastavena na 8, $count je tedy ve finle 8k.

bcrypt

password_hash
password_verify

Bylo by fajn, kdyby WordPress na novjch verzch pouval bcrypt. Od PHP 5.5 je dostupn pomoc funkc password_hash() a password_verify(). Dal vhodn funkce pro ukldn uivatelskch hesel jsou Argon2i, scrypt, PBKDF2. Jestli chcete vdt vce, podvejte se na moj pednku o ukldn uivatelskch hesel.

WordPress funguje i na PHP 5.2.4 a novj funkce tedy nelze pouvat (samotn bcrypt je pouiteln od PHP 5.3.7, ve starch verzch ml problm s hesly s diakritikou). Bohuel pr existuj lid, kte pechz z novjch verz PHP na star (eh, pro?), take nejde pouvat bcrypt pouze na novjch verzch a pro ty 10 let star verze PHP nechat nevhodnou MD5. Natst existuj pluginy, kter umon WordPressu pouvat bcrypt, nap. ten od Roots.

HTTPS=
How To Transfer Private Shit

O HTTPS toho bylo ji napsno docela dost, ale evidentn to stle nesta. Bylo by pardn, kdyby WordPress HTTPS vyadoval. Minimln pro administraci, jinak se me stt, e se do n dostane njak mizera, kdy se v kavrn teba nevdomky pipojte na zkenou Wi-Fi a zanete editovat pspvek. True story, bro.

Borek napsal na Twitter, e zakladatel WordPressu publikoval lnek na Medium. Na Valentna. A Daniel tomu dal . Ten lnek je o podepisovn aktualizac, to WordPressu chyb. Operan systmy sv aktualizace maj podepsan ji dlouho.

Internet je nebezpen msto a mohlo by se stt, e aktualizace pi stahovn nkdo zmn a WordPress zane pouvat njak nebezpen upraven kd. Pokud by byly aktualizace podepsan, tak WordPress zmnu detekuje a aktualizace nenainstaluje. Natst WordPress bn neaktualizujete pes veejnou Wi-Fi v kavrn a tak provst takovto tok je pomrn nkladn, tonk by toti musel ovldnout routery po cest mezi vam WordPressem a aktualizanmi servery. Podpisy navc nepomohou pokud nkdo napadne samotn aktualizan server, to si pak upravenou aktualizaci me podepsat sm tonk a WordPress nic nepozn.

Zakladatel WordPressu Matt Mullenweg v lnku nakonec uvedl, e podepisovn aktualizac nkdy v budoucnu pidaj, e je to pr dobr npad a e me pomoci.

SELECT FROM
WHERE name = %s

Pi posln dotaz do databze oddluje WordPress dotaz od dat pomoc zstupnch znak jako nap. %s, data sprvn oescapuje a zstupn znaky jimi nahrad. To brn toku SQL Injection, pi kterm se z dat zmn i samotn dotaz. Nkdy se takovmu zpsobu posln dotaz k prepared statements.

123

WHERE id = ?

Jene prepared statements funguj trochu jinak poslaj dotazy nadvakrt. Nejdve se z PHP na databzov server pole pkaz PREPARE se zstupnmi znaky, typicky otaznky. Server si piprav ve, co pro sputn takovho dotazu bude potebovat avrt dotaz pipraven. Teprve pot se dalm pkazem EXECUTE odelou data, kter server umst na sprvn msto v pamti a provede s nimi danou operaci. Vzhledem k tomu, e ve chvli pijmn dat je na serveru pvodn dotaz ji zparsovn a zahozen, tak nelze pomoc dat ovlivnit. Je to naprosto inn obrana proti SQL Injection. Nevhodou je dvojnsobn komunikace s databzovm serverem, ale ta se sete ve chvli, kdy chceme spoutt jeden dotaz s rznmi hodnotami, sta pak jen opakovan volat EXECUTE. Skutenmu oddlen dat od dotazu na rovni serveru se obas k serverov nebo nativn prepared statements.

123

WHERE
id = ?

WHERE id = 123

WordPress msto toho pouv tzv. emulovan prepared statements. J mm radji termn vzn promnnch, pesnji vyjaduje zpsob prce s dotazy. Vzn promnnch funguje tak, e PHP samo sprvn oet data a nalep je na uren zstupn msto v dotazu, ve WordPressu jsou to %s, %d a dal. Pot se na databzov server odele cel dotaz najednou, vetn sprvn oetench hodnot. Vhoda oproti opravdovm prepared statements je v rychlosti pro neopakujc se dotazy se serverem sta komunikovat jen jednou. Programtor ale ani tak nemus myslet na run escapovn, take je to takov rozumn kompromis.

Toto je kus kdu, kter se prv o escapovn star. Vzn promnnch je implementovno v metod prepare(), najdete ji ve td wpdb. Vimnte si voln vsprintf() na konci, to je ta funkce, kter nahrad zstupn znaky jako %s za vlastn hodnoty. Cel dotaz vetn hodnot se pak odele metodou query(), volanou napklad z get_row() a dalch.

\xBF' UNION
mysql_escape_string()
\xBF\x5C' UNION

Pi pouvn emulovanch prepared statements je i pesto mon provst tok SQL Injection, pokud se nastav patn znakov sada. Escaptor (pesnji databzov klient, tedy PHP) nemus pak vdt, v jak znakov sad jsou data, kter m oetovat. Ve znakov sad GBK existuje dvoubajtov znak, kter kon zptnm lomtkem (hexadecimln 5C), take kdy se escapovnm ped apostrof pid, tak je na serveru zase porn pedchozm bajtem. Server ho nevid, protoe je soust toho dvoubajtovho znaku. Podvejte se na mj pklad, kter ukazuje sprvn i patn nastaven znakov sady. WordPress znakovou sadu nastavuje, ale i tak by bylo lep, kdyby byla monost pouvat nativn prepared statements.

Kdybychom znakovou sadu nenastavili a databze byla v GBK, tak by se tohle oescapovalo na tohle, prost ped apostrof se d zptn lomtko, co vypad jako ok, jene BF 5C je validn aj, jeden vcebajtovej znak, take zas nm tam zstvPi nastaven sprvn sady a pouit real_escape_string se d zptn lomtko i ped BF

Content Security Policy (CSP) je vcelku nov vc. No, nov Pvodn npad vznikl v roce 2004, prvn verze standardu v roce 2012. Pomoc CSP mete vytvoit seznam zdroj, kter me prohle do strnky nast, tzv. whitelist. Prohlei seznam pedte ve form HTTP hlaviky, kterou odelete ze serveru.

Content-Security-Policy: default-src 'self'

Toto je asi nejjednodu varianta CSP. Direktiva default-src s hodnotou 'self' k, e do strnky se mohou nast pouze zdroje z aktuln domny, resp. originu. Tedy ikdyby se tonkovi do HTML kdu podailo vloit obrzek nebo znaku , tak browser nic takovho vbec nebude stahovat. CSP je druh rove obrany proti Cross-Site Scriptingu a dalm podobnm tokm. Kdy nco zapomenete oetit, tak Content Security Policy me vae uivatele ochrnit.

Content-Security-Policy:
default-src 'self';
img-src 'self' https://www.google-analytics.com; script-src 'self' 'unsafe-inline'

Takto poslan HTTP hlavika browseru k, e defaultn m zdroje natat jen z aktulnho originu. Pomoc img-src rozme monost natat obrzky navc zhttps://www.google-analytics.com. JavaScript me nast zase jen z aktulnho originu a navc me spoutt i tzv. inline skripty, tedy ve, co je mezi znakou a , a ve v atributech onclick a dalch podobnch.

CSP3Content Security Policy
Level 3

Jene vyjmenovvat vechny zdroje je bh na dlouhou tra, navc pi pouvn nstroj jako nap. Google Tag Manager dopedu ani neznme, jak zdroje do strnky budeme natat. Nov verze CSP toto e, nasazen na nov i existujc weby je o dost jednodu. Zvyuje se tak ance, e to vrobci web udlaj atm sv nvtvnky zase o nco vce ochrn. Bylo by pardn, kdyby WordPress obsah hlaviky Content-Security-Policy uml jednodue vygenerovat nebo nastavit.

Content-Security-Policy:
script-src 'strict-dynamic' 'nonce-rAnd0m123'

HTML:

CSP3 pidv podporu pro 'strict-dynamic'. Tato hodnota k, e kdy u je jednou skript povolen, tak me do strnky pidvat dal skripty a ty to povolen automaticky zdd. V ppad pouit 'strict-dynamic' je ale dostupn jen jedin monost, jak skripty povolit: oznaen pomoc atributu nonce. Jeho hodnota by mla bt jin pro kad naten strnky. Tou hodnotou meme oznait vce skript v HTML kdu, do CSP hlaviky ji pak pidme pomoc 'nonce-'. Cel si to mete vyzkouet na m strnce s pklady.

Content-Security-Policy:
script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:; object-src 'none'; report-uri https://report-uri.io/r/

Univerzln hlavika vypad takto. Browsery s podporou CSP3 pouij 'strict-dynamic' a 'nonce-', ty ostatn pak bu jen 'nonce-' nebo ty dal direktivy. object-src 'none' zakazuje natn plugin, Cross-Site Scripting lze nkdy provst i pomoc nich. Prohlee s podporou CSP um navc poslat informace otom, kdy a kde byla jak politika poruena. Pro zobrazovn report pouijte report-uri.io, vygenerujte si tam adresu, na kterou reporty budete poslat a tu pak pouijte v direktiv report-uri.

csp-evaluator.withgoogle.com

Content Security Policy vypad celkem sloit, co? Kdy to nastavte blb, tak se bude takov politika dt obejt. Jene co to je blb? Podvejte se na CSP validtor od Google (maj i extenzi pro Chrome), zadejte tam URL strnek nebo rovnou HTTP hlaviku a hned se dozvte, jak jste na tom. Je tam i pklad bezpenho nastaven.

Michal paek
www.michalspacek.com @spazef0rze

Monost, jak by se dal WordPress z hlediska zabezpeen vylepit je mnoho. Na strnce projektu CMS Airship naleznete srovnn bezpenostnch fur znmch arozench CMS, nco z toho si vyberte a zante na tom makat. Dky!