SlideShare une entreprise Scribd logo
1  sur  21
Jak jsme zlepšili
zabezpečení Slevomat.cz
Michal Špaček
@spazef0rze
www.michalspacek.cz
Tyto slajdy obsahují poznámky nejen pro ty, kteří na přednášce nebyli.
$this context→
Slevomat má ~1M zákazníků, v databázi ~1.8M uživatelských účtů a web
slevomat.cz denně navštíví přes 200k návštěvníků. Slevomat v roce 2013 dosáhl
miliardového obratu, má vlastní značku zboží i vlastní sklad. Ve Slevomatu pracuje
150 lidí, vývojové oddělení čítá 10 hlav, mezi nimi např. @kukulich, @vasekpurchart
nebo @patrikvotocek. Nechceš se k nim přidat? Slevomat používá PHP 5.5, Nette
2.1, Elasticsearch a MySQL resp. Percona Server, který obslouží ~2.5M dotazů za
hodinu. Čísla kreditních karet nejsou uložena v databázi Slevomatu, pamatuje si je
platební brána. Uživatelé mohou na svých účtech mít kredity, kterými mohou platit,
ale nedají se převádět na jiného uživatele. Aktualizace: všechny informace na tomto
slajdu jsou z roku 2014 a mohou se od aktuálního stavu lišit.
Dříve bylo možné se přihlásit z jakékoliv stránky – po kliknutí na tlačítko vpravo
nahoře se rovnou objevil přihlašovací formulář a to i přesto, že stránka přišla po
nezabezpečeném HTTP. Formulář se sice odesílal šifrovaně pomocí HTTPS, ale
mohl být po cestě do prohlížeče změněn tak, aby se odesílal někam úplně jinam.
Přihlašování jsme tedy přesunuli na samostatnou stránku, která se stahuje po
HTTPS, obsah formuláře tedy do prohlížeče dorazí v původním stavu.
Web slevomat.cz zatím neběží celý na HTTPS (update: od července 2014 již ano),
takže ačkoliv se případný mizera nedostane k přihlašovacím údajům změnou
formuláře po cestě, může se odposlechem dostat k session id cookie, protože ta se
přenáší i po nezabezpečeném HTTP. Až bude celý web přístupný pouze po HTTPS,
cookie označíme jako Secure a tím zajistíme, že se bude přenášet jen po
šifrovaném HTTPS a nepůjde odposlechnout. Direktivy session.cookie_httponly
a session.use_only_cookies pro obranu před útoky na session máme
samozřejmě zapnuté už docela dlouho.
session.cookie_secure
Při relativně velké zátěži webových serverů Slevomatu nechceme přechod na
zabezpečené HTTPS udělat najednou, ale raději postupně přesunujeme jednotlivé
části webu. Velmi brzy bude celý web přístupný jen a pouze přes HTTPS. A pak
zas můžeme vrátit přihlašovací formulář do Lightboxu na každou stránku.
HTTP Strict Transport Security
Strict-Transport-Security:
max-age=31536000; includeSubDomains
Až bude celý web přístupný pouze pomocí HTTPS, budeme posílat hlavičku
Strict-Transport-Security, která zajístí to, že se prohlížeč ani nebude pokoušet
server kontaktovat po HTTP a rovnou bude po stanovenou dobu všechny odkazy
sám převádět na HTTPS. Zabráníme tím man-in-the-middle útokům, které převádějí
šifrované HTTPS spojení na obyčejné HTTP. Hlavičku podporuje většina moderních
browserů, IE ji bude podporovat od verze 12.
Přenos hesel a session ids tedy bude zabezpečen docela dobře. K uživatelským
údajům se ale dá dostat i jinak, než odposlechem. Třeba tak, že jednoho krásného
dne najdete na serveru 12 GB záloh cizích databází, protože je tam někdo kdysi
nahrál a nesmazal. Opravdu se to stává a je lepší počítat s tím, že i vaše databáze
se může někde objevit.
$dibi
→select('jmeno')
where(→ "id = $_GET[id]");
Ale nemusí to být jenom zálohy na nepatřičných místech. Firemní údaje a hesla
uživatelů se z databáze dají vysosat třeba úspěšným provedením útoku SQL
Injection. Spousta uživatelů používá jedno heslo na více místech a když z
jednoho takového místa to heslo unikne, tak … raději nedomýšlet. A ano, SQL
Injection lze provést i v Nette, Dibi a PDO, pokud se tyto nástroje použijí trochu
nešikovně. Žádný nástroj automagicky nevyřeší zabezpečení webu.
8b8f05049b2114ad3d33
0db391e78549670d6b4b
Slevomat dříve heslo před uložením zahashoval pomocí algoritmu SHA-1, aby
nebylo tak jednoduché ho získat, pokud by se k databázi nějakým způsobem dostal
někdo nepovolaný. Heslo nebylo saltované, takže nebylo chráněno proti tzv.
narozeninovým útokům, ani proti použití předpočítaných tabulek. Jenže ty se už
dnes stejně moc nepoužívají, hesla se crackují hrubou silou, slovníkovými nebo
hybridními útoky. Každý obyčejný laptop umí spočítat desítky miliónů SHA-1
hashů za vteřinu a moderní grafické karty jsou stokrát rychlejší. Cracknout takové
běžné heslo hashované SHA-1 je tedy otázkou maximálně pár minut a ani salt by
crackování nezpomalil. Zkuste si to sami pomocí nástroje oclHashcat.
cHJvZDE=;GwEuCSSgBCL
x0BHHAAb8IA==;kvmDV/
DEJ3H+how7bErLa+/xap
V2282MmISXqVo8xREfnB
KcNmAixIaDDnYkODCu9K
W3+6sbM04W7Tm3w1S+NQ==
Nyní Slevomat ukládá hesla tak, že heslo zahashuje relativně pomalým algoritmem
bcrypt, aktuálně s cost parametrem 10. Výsledný hash se navíc zašifruje pomocí
AES-256-CBC a poté se uloží do databáze. Je to klacek pod nohy,
pravděpodobnost, že se mizera dostane k databázi a zároveň ke konfiguračnímu
souboru aplikace, ve kterém je uložen šifrovací klíč, je mnohem menší, než že se
dostane jenom k databázi. A pokud získá databázi i klíč, tak po rozšifrování má před
sebou pořád ty bcrypt hashe. Výše je mé aktuální heslo tak, jak je uloženo v
produkční databázi Slevomatu. Všimněte si id klíče, inicializačního vektoru
a šifrovaného hashe, vše odděleno středníkem a zakódováno do Base64.
password_hash(…, PASSWORD_DEFAULT)
ircmaxell/password_compat
Pro pouhé hashování hesel algoritmem bcrypt použijte funkci password_hash()
a pro ověření password_verify(). Tyto funkce jsou dostupné až od PHP 5.5, ale
pro starší PHP (od PHP 5.3.7) existuje knihovna password_compat, která tyto
funkce implementuje v čistém PHP. Najdete ji na GitHubu nebo ji můžete
nainstalovat pomocí Composeru. Jednoduchý příklad použití najdete u mě na
GitHubu na https://github.com/spaze/encrypt-hash-password-php v souboru
example-hash.php.
mcrypt_encrypt()
MCRYPT_RIJNDAEL_128
Pro následné šifrování hashů hesel pomocí AES-256 v PHP použijte funkce
mcrypt_encrypt() a mcrypt_decrypt() z rozšíření mcrypt. Aktualizace: mcrypt
je depracated od PHP 7.1, použijte raději na konci odstavce zmiňovanou knihovnu
defuse/php-encryption. Bloková šifra AES je variantou šifry Rijndael s velikostí bloku
128 bitů, použijeme tedy konstantu MCRYPT_RIJNDAEL_128. Hodnota 256 v názvu
znamená velikost použitého šifrovacího klíče v bitech. Pro ukládání hashů je vhodný
režim CBC (Cipher-block chaining), ten při volání mcrypt_encrypt() zvolíme
pomocí MCRYPT_MODE_CBC. Inicializační vektor vytvoříme funkcí
mcrypt_create_iv() s parametrem MCRYPT_DEV_URANDOM. Jednoduchý příklad
najdete opět na GitHubu: https://github.com/spaze/encrypt-hash-password-php v
souboru example-encrypthash.php. Pro obecné šifrování dat raději použijte
knihovnu https://github.com/defuse/php-encryption, která přidává autentizaci
zašifrovaných dat pomocí metody Encrypt-then-MAC.
aes(bcrypt(sha1(…)))
aes(bcrypt(…))
Ve Slevomatu jsme chtěli zabezpečit i hesla uživatelů, kteří se dlouho nepřihlásili.
Vzali jsme tedy stávající SHA-1 hashe, zahashovali bcryptem a pak zašifrovali AES-
256. Taková hesla jsme si označili, abychom při ověřování věděli, že z hesla
zadaného uživatelem máme nejdříve udělat SHA-1 hash a až pak s ním pracovat
dále. Když se takový uživatel úspěšně přihlásí, tak zadané heslo v čitelné podobě
zahashujeme jen bcryptem s vynecháním SHA-1, hash zašifrujeme a výsledek
uložíme do databáze. To děláme i při nastavení hesla nového. Mezikrok s SHA-1 je
lepší, než vynucená změna hesla všech uživatelů, je ale zbytečný a pokud můžeme,
tak ho odstraníme.
bcrypt(token)
Pomocí funkce password_hash() hashujeme i tokeny pro semi-permanentní
přihlášení i pro přihlášení pomocí Facebooku. V čitelné podobě je v databázi
nemáme. Token z cookie pak ověřujeme stejně jako heslo při přihlašování, tedy
funkcí password_verify(). Hash tokenu v databázi nalezneme podle identifikátoru
uživatele z cookie. Aktualizace: tokeny jsou na rozdíl od běžných hesel náhodně
generované a dlouhé minimálně 20 bajtů, pro uložení by tedy stačilo použít funkci
hash('sha256', $token) a pro ověření funkci hash_equals().
Funkci Zapomenuté heslo máme vyřešenu tak, že uživateli posíláme odkaz, který
obsahuje token, jehož platnost je časově omezena – momentálně na 30 minut od
odeslání odkazu. Tento interval by neměl přesáhnout 60 minut. E-mail nově
obsahuje i odkaz pro zneplatnění tokenu. Token hashujeme bcryptem, v databázi
není uložen v čitelné podobě. Zákaznické podpoře jsme odebrali možnost
nastavovat hesla uživatelům v administraci Slevomatu, ale pro některé domény jsme
tuto možnost museli vrátit zpět. Centrum.cz totiž doručuje některé e-maily s
mnohahodinovým zpožděním a uživatel tak prošvihne interval, během kterého je
token platný a o pomoc pak žádá právě zákaznickou podporu.
Vaše heslo je: •••••
Hesla nově nikdy neposíláme e-mailem, ani při registraci. Veškeré změny
logujeme a víme kdo, kdy a z jaké IP adresy změnil heslo nebo e-mailovou adresu.
Uživatele po změně informujeme, pro jistotu. Brzy chceme změnit politiku
vytváření hesel, současné omezení na min. 5 znaků je dnes již nevyhovující. Nová
hesla by měla mít minimálně 8 znaků. Maximální povolená délka hesla je 4096
znaků, delší hesla příliš zatěžují server při hashování bcryptem. Aktualizace:
implementace bcryptu v PHP delší hesla automaticky ořezává na 72 znaků, toto
omezení je na Slevomatu nadbytečné.
Content Security Policy
Ve Slevomatu používáme šablonovací systém Latte, který je součástí Nette
Frameworku. Latte automagicky ošetřuje vypisované proměnné, ale i přesto se
může stát, že uděláte chybu, třeba při tvorbě vlastních maker, a váš web bude
zranitelný pomocí útoku Cross-Site Scripting (XSS). Ke snížení dopadu případného
úspěšného útoku bude Slevomat brzy posílat HTTP hlavičku Content-Security-
Policy, která vyjmenovává zdroje (whitelisting), odkud může prohlížeč do stránky
vkládat obrázky, kaskádové styly, JavaScript a další. Browser nebude spouštět ani
inline JavaScript, pokud se pošle i hodnota 'unsafe-inline', JavaScriptový kód
pak musí být v externích souborech. Na přesunu pilně pracujeme.
<script>
var foo = 123;
var color = 'purple';
</script>
Posílat hodnotu 'unsafe-inline' rozhodně chcete, zakázáním spouštění
JavaScriptu vloženého přímo do stránky zabráníte úspěšnému provedení útoku
Cross-Site Scripting i kdyby někdo nějak do stránky nějaký JavaScript vložil.
Občas se přímo do stránky úmyslně vkládá nějaká konfigurace, ovšem pokud je to
uděláno výše uvedeným způsobem, tak to přestane fungovat. S 'unsafe-inline'
momentálně nefunguje ani kód Google Tag Manageru, a to ani s využitím
experimentální podpory nonce-source z připravované specifikace CSP 1.1 v
Chrome 35. Slevomat používá Google Tag Manager a 'unsafe-inline' je pro nás
tedy momentálně nepoužitelné.
<script id="conf" type="text/json">
{
"foo" = "123",
"color" = "purple"
}
</script>
<script src="code.js"></script>
Konfiguraci ve stránce je možné zachovat, jen je potřeba změnit typ obsahu značky
SCRIPT na text/json. JSON není kód, nelze spustit a browser ho tedy při
'unsafe-inline' nemusí blokovat. V code.js se pak k hodnotám dostanete takto:
var c = document.getElementById('conf'); var d =
JSON.parse(c.textContent || c.innerHTML);.
$c = stream_context_create(array(
'ssl' => array(
'verify_peer' => true,
'verify_depth' => 9,
'cafile' => $caFile,
'disable_compression' => true,
)
));
Pokud potřebujeme komunikovat s nějakým API, používáme k tomu šifrovaný
protokol HTTPS. Pro bezpečnou komunikaci musíme také ověřovat, že opravdu
komunikujeme třeba s bankou a že to není nějaký mizera, který se za banku vydává.
Vypnutím TLS komprese se pak bráníme proti útoku CRIME. Takto bude defaultně
nastaveno i PHP 5.6+.
JDE TO!
www.michalspacek.cz
V zabezpečování Slevomatu a uživatelských dat budeme samozřejmě pokračovat
dále, ještě nás čeká spousta práce, ale když se chce, tak to jde. Snad jsem vás také
trochu inspiroval a pokud byste chtěli se zabezpečením webů a aplikací pomoci,
napište mi, rád pomohu. Kontakty jsou uvedeny na mém webu. Díky!

Contenu connexe

Tendances

HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS)HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS)Michal Špaček
 
Jak zlepšit zabezpečení čtvrtiny celého webu
Jak zlepšit zabezpečení čtvrtiny celého webuJak zlepšit zabezpečení čtvrtiny celého webu
Jak zlepšit zabezpečení čtvrtiny celého webuMichal Špaček
 
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)Michal Špaček
 
HTTPS (a šifrování) všude
HTTPS (a šifrování) všudeHTTPS (a šifrování) všude
HTTPS (a šifrování) všudeMichal Špaček
 
WebTop100 Technické chyby, výkon a bezpečnost
WebTop100 Technické chyby, výkon a bezpečnostWebTop100 Technické chyby, výkon a bezpečnost
WebTop100 Technické chyby, výkon a bezpečnostMichal Špaček
 
Bezpečnost e-shopů (HTTPS, XSS, CSP)
Bezpečnost e-shopů (HTTPS, XSS, CSP)Bezpečnost e-shopů (HTTPS, XSS, CSP)
Bezpečnost e-shopů (HTTPS, XSS, CSP)Michal Špaček
 
Lámání a ukládání hesel
Lámání a ukládání heselLámání a ukládání hesel
Lámání a ukládání heselMichal Špaček
 
Víceúrovňová obrana vysvětlená na Cross-Site Scriptingu
Víceúrovňová obrana vysvětlená na Cross-Site ScriptinguVíceúrovňová obrana vysvětlená na Cross-Site Scriptingu
Víceúrovňová obrana vysvětlená na Cross-Site ScriptinguMichal Špaček
 
Bezpečnost na mobilních zařízeních
Bezpečnost na mobilních zařízeníchBezpečnost na mobilních zařízeních
Bezpečnost na mobilních zařízeníchMichal Špaček
 
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)Michal Špaček
 
Bezpečnostní útoky na webové aplikace
Bezpečnostní útoky na webové aplikaceBezpečnostní útoky na webové aplikace
Bezpečnostní útoky na webové aplikaceMichal Špaček
 
Kolik webových útoků znáš...
Kolik webových útoků znáš...Kolik webových útoků znáš...
Kolik webových útoků znáš...Michal Špaček
 
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...New Media Inspiration
 
Bezpečnost na webu
Bezpečnost na webuBezpečnost na webu
Bezpečnost na webuMiloš Janda
 
Website Security & WordPress (Peter Gramantik)
Website Security & WordPress (Peter Gramantik)Website Security & WordPress (Peter Gramantik)
Website Security & WordPress (Peter Gramantik)wcsk
 
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5Bezpečnostní útoky na webové aplikace, Čtvrtkon 5
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5Michal Špaček
 
HTTPS zdarma a pro všechny - LinuxDays 2015
HTTPS zdarma a pro všechny - LinuxDays 2015HTTPS zdarma a pro všechny - LinuxDays 2015
HTTPS zdarma a pro všechny - LinuxDays 2015tomashala
 
WordCamp Prague 2014 - Website security cz
WordCamp Prague 2014 - Website security czWordCamp Prague 2014 - Website security cz
WordCamp Prague 2014 - Website security czpeter_sucuri
 

Tendances (20)

Přechod na HTTPS
Přechod na HTTPSPřechod na HTTPS
Přechod na HTTPS
 
HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS)HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS)
 
Jak zlepšit zabezpečení čtvrtiny celého webu
Jak zlepšit zabezpečení čtvrtiny celého webuJak zlepšit zabezpečení čtvrtiny celého webu
Jak zlepšit zabezpečení čtvrtiny celého webu
 
Zapomeňte vaše hesla
Zapomeňte vaše heslaZapomeňte vaše hesla
Zapomeňte vaše hesla
 
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)
Víte, že nevíte, že já vím, že nevíte? (WebTop100 2014)
 
HTTPS (a šifrování) všude
HTTPS (a šifrování) všudeHTTPS (a šifrování) všude
HTTPS (a šifrování) všude
 
WebTop100 Technické chyby, výkon a bezpečnost
WebTop100 Technické chyby, výkon a bezpečnostWebTop100 Technické chyby, výkon a bezpečnost
WebTop100 Technické chyby, výkon a bezpečnost
 
Bezpečnost e-shopů (HTTPS, XSS, CSP)
Bezpečnost e-shopů (HTTPS, XSS, CSP)Bezpečnost e-shopů (HTTPS, XSS, CSP)
Bezpečnost e-shopů (HTTPS, XSS, CSP)
 
Lámání a ukládání hesel
Lámání a ukládání heselLámání a ukládání hesel
Lámání a ukládání hesel
 
Víceúrovňová obrana vysvětlená na Cross-Site Scriptingu
Víceúrovňová obrana vysvětlená na Cross-Site ScriptinguVíceúrovňová obrana vysvětlená na Cross-Site Scriptingu
Víceúrovňová obrana vysvětlená na Cross-Site Scriptingu
 
Bezpečnost na mobilních zařízeních
Bezpečnost na mobilních zařízeníchBezpečnost na mobilních zařízeních
Bezpečnost na mobilních zařízeních
 
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)
Minulé století volalo (Cross-Site Scripting + BeEF + CSP demo)
 
Bezpečnostní útoky na webové aplikace
Bezpečnostní útoky na webové aplikaceBezpečnostní útoky na webové aplikace
Bezpečnostní útoky na webové aplikace
 
Kolik webových útoků znáš...
Kolik webových útoků znáš...Kolik webových útoků znáš...
Kolik webových útoků znáš...
 
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...
NMI14 Michal Špaček - Jak vytvářet, ukládat, používat hesla, jaké nástroje k ...
 
Bezpečnost na webu
Bezpečnost na webuBezpečnost na webu
Bezpečnost na webu
 
Website Security & WordPress (Peter Gramantik)
Website Security & WordPress (Peter Gramantik)Website Security & WordPress (Peter Gramantik)
Website Security & WordPress (Peter Gramantik)
 
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5Bezpečnostní útoky na webové aplikace, Čtvrtkon 5
Bezpečnostní útoky na webové aplikace, Čtvrtkon 5
 
HTTPS zdarma a pro všechny - LinuxDays 2015
HTTPS zdarma a pro všechny - LinuxDays 2015HTTPS zdarma a pro všechny - LinuxDays 2015
HTTPS zdarma a pro všechny - LinuxDays 2015
 
WordCamp Prague 2014 - Website security cz
WordCamp Prague 2014 - Website security czWordCamp Prague 2014 - Website security cz
WordCamp Prague 2014 - Website security cz
 

Similaire à Zabezpečení Slevomatu

WordCamp Brno 2017 - rychlý a bezpečný web
WordCamp Brno 2017  - rychlý a bezpečný webWordCamp Brno 2017  - rychlý a bezpečný web
WordCamp Brno 2017 - rychlý a bezpečný webVladimír Smitka
 
Bezpečnost WordPress pro začátečníky
Bezpečnost WordPress pro začátečníkyBezpečnost WordPress pro začátečníky
Bezpečnost WordPress pro začátečníkyVladimír Smitka
 
WordPress - základy bezpečnosti
WordPress - základy bezpečnostiWordPress - základy bezpečnosti
WordPress - základy bezpečnostiVladimír Smitka
 
Hesla a vícefaktorová autentizace ve WP
Hesla a vícefaktorová autentizace ve WPHesla a vícefaktorová autentizace ve WP
Hesla a vícefaktorová autentizace ve WPVladimír Smitka
 
Bezpečnost Wordpressu - 4. WP konference
Bezpečnost Wordpressu - 4. WP konferenceBezpečnost Wordpressu - 4. WP konference
Bezpečnost Wordpressu - 4. WP konferenceVladimír Smitka
 
WordCamp Praha 2016 - Bezpečnost WordPress
WordCamp Praha 2016 - Bezpečnost WordPressWordCamp Praha 2016 - Bezpečnost WordPress
WordCamp Praha 2016 - Bezpečnost WordPressVladimír Smitka
 
Javascript na steroidech
Javascript na steroidechJavascript na steroidech
Javascript na steroidechseznamVyvojari
 
Symposium 2022 - Proc upgradovat ma Domino 1201.pdf
Symposium 2022 - Proc upgradovat ma Domino 1201.pdfSymposium 2022 - Proc upgradovat ma Domino 1201.pdf
Symposium 2022 - Proc upgradovat ma Domino 1201.pdfMartin Hansgut
 
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)Jakub Kulhan
 
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnace
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnaceRockaway Azure Hackathon 2016 – Kickoff Meeting prezetnace
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnaceRockawayCapital
 
Optimalizace webových aplikací
Optimalizace webových aplikacíOptimalizace webových aplikací
Optimalizace webových aplikacíVašek Purchart
 
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...Security Session
 
06 prez10(tvorba webu)
06 prez10(tvorba webu)06 prez10(tvorba webu)
06 prez10(tvorba webu)olc_user
 
PoSobota 96 ČB 28.4.2018
PoSobota 96 ČB 28.4.2018PoSobota 96 ČB 28.4.2018
PoSobota 96 ČB 28.4.2018Brilo Team
 
Co sledovat a jak měřit u mobilního webu
Co sledovat a jak měřit u mobilního webuCo sledovat a jak měřit u mobilního webu
Co sledovat a jak měřit u mobilního webuAkce Dobrého webu
 
Nejčastejší problémy WordPress webů
Nejčastejší problémy WordPress webůNejčastejší problémy WordPress webů
Nejčastejší problémy WordPress webůVladimír Smitka
 

Similaire à Zabezpečení Slevomatu (19)

WordCamp Brno 2017 - rychlý a bezpečný web
WordCamp Brno 2017  - rychlý a bezpečný webWordCamp Brno 2017  - rychlý a bezpečný web
WordCamp Brno 2017 - rychlý a bezpečný web
 
Bezpečnost WordPress pro začátečníky
Bezpečnost WordPress pro začátečníkyBezpečnost WordPress pro začátečníky
Bezpečnost WordPress pro začátečníky
 
Instalace WordPress
Instalace WordPressInstalace WordPress
Instalace WordPress
 
WordPress - základy bezpečnosti
WordPress - základy bezpečnostiWordPress - základy bezpečnosti
WordPress - základy bezpečnosti
 
Hesla a vícefaktorová autentizace ve WP
Hesla a vícefaktorová autentizace ve WPHesla a vícefaktorová autentizace ve WP
Hesla a vícefaktorová autentizace ve WP
 
Bezpečnost Wordpressu - 4. WP konference
Bezpečnost Wordpressu - 4. WP konferenceBezpečnost Wordpressu - 4. WP konference
Bezpečnost Wordpressu - 4. WP konference
 
WordCamp Praha 2016 - Bezpečnost WordPress
WordCamp Praha 2016 - Bezpečnost WordPressWordCamp Praha 2016 - Bezpečnost WordPress
WordCamp Praha 2016 - Bezpečnost WordPress
 
Javascript na steroidech
Javascript na steroidechJavascript na steroidech
Javascript na steroidech
 
Symposium 2022 - Proc upgradovat ma Domino 1201.pdf
Symposium 2022 - Proc upgradovat ma Domino 1201.pdfSymposium 2022 - Proc upgradovat ma Domino 1201.pdf
Symposium 2022 - Proc upgradovat ma Domino 1201.pdf
 
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)
#golang @SkrzCzDev (Skrz DEV Cirkus 21.10.2015)
 
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnace
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnaceRockaway Azure Hackathon 2016 – Kickoff Meeting prezetnace
Rockaway Azure Hackathon 2016 – Kickoff Meeting prezetnace
 
Wordfence 2016
Wordfence 2016Wordfence 2016
Wordfence 2016
 
Optimalizace webových aplikací
Optimalizace webových aplikacíOptimalizace webových aplikací
Optimalizace webových aplikací
 
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...
Zabezpečení nejen SSH na serveru pomocí Fail2Ban a jednoduchého honeypotu. / ...
 
06 prez10(tvorba webu)
06 prez10(tvorba webu)06 prez10(tvorba webu)
06 prez10(tvorba webu)
 
PoSobota 96 ČB 28.4.2018
PoSobota 96 ČB 28.4.2018PoSobota 96 ČB 28.4.2018
PoSobota 96 ČB 28.4.2018
 
Co sledovat a jak měřit u mobilního webu
Co sledovat a jak měřit u mobilního webuCo sledovat a jak měřit u mobilního webu
Co sledovat a jak měřit u mobilního webu
 
Nejčastejší problémy WordPress webů
Nejčastejší problémy WordPress webůNejčastejší problémy WordPress webů
Nejčastejší problémy WordPress webů
 
Výkon WordPress
Výkon WordPressVýkon WordPress
Výkon WordPress
 

Plus de Michal Špaček

Fantom Opery, "VPN" a Secure Proxy v Opeře
Fantom Opery, "VPN" a Secure Proxy v OpeřeFantom Opery, "VPN" a Secure Proxy v Opeře
Fantom Opery, "VPN" a Secure Proxy v OpeřeMichal Špaček
 
Quality of Life, Multiple Lines of Defense
Quality of Life, Multiple Lines of DefenseQuality of Life, Multiple Lines of Defense
Quality of Life, Multiple Lines of DefenseMichal Špaček
 
Disclosing password hashing policies
Disclosing password hashing policiesDisclosing password hashing policies
Disclosing password hashing policiesMichal Špaček
 
Operations security (OPSEC) in IT
Operations security (OPSEC) in ITOperations security (OPSEC) in IT
Operations security (OPSEC) in ITMichal Špaček
 
HTTP Strict Transport Security (HSTS), English version
HTTP Strict Transport Security (HSTS), English versionHTTP Strict Transport Security (HSTS), English version
HTTP Strict Transport Security (HSTS), English versionMichal Špaček
 
I forgot my password – what a secure password reset needs to have and why
I forgot my password – what a secure password reset needs to have and whyI forgot my password – what a secure password reset needs to have and why
I forgot my password – what a secure password reset needs to have and whyMichal Špaček
 
The problem with the real world
The problem with the real worldThe problem with the real world
The problem with the real worldMichal Špaček
 
Defense in Depth Web Inkognito 12/2013
Defense in Depth Web Inkognito 12/2013Defense in Depth Web Inkognito 12/2013
Defense in Depth Web Inkognito 12/2013Michal Špaček
 
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013Bezpečnost webových aplikací Web Inkognito VŠE 05/2013
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013Michal Špaček
 

Plus de Michal Špaček (11)

Fantom Opery, "VPN" a Secure Proxy v Opeře
Fantom Opery, "VPN" a Secure Proxy v OpeřeFantom Opery, "VPN" a Secure Proxy v Opeře
Fantom Opery, "VPN" a Secure Proxy v Opeře
 
Quality of Life, Multiple Lines of Defense
Quality of Life, Multiple Lines of DefenseQuality of Life, Multiple Lines of Defense
Quality of Life, Multiple Lines of Defense
 
Disclosing password hashing policies
Disclosing password hashing policiesDisclosing password hashing policies
Disclosing password hashing policies
 
Operations security (OPSEC) in IT
Operations security (OPSEC) in ITOperations security (OPSEC) in IT
Operations security (OPSEC) in IT
 
HTTP Strict Transport Security (HSTS), English version
HTTP Strict Transport Security (HSTS), English versionHTTP Strict Transport Security (HSTS), English version
HTTP Strict Transport Security (HSTS), English version
 
I forgot my password – what a secure password reset needs to have and why
I forgot my password – what a secure password reset needs to have and whyI forgot my password – what a secure password reset needs to have and why
I forgot my password – what a secure password reset needs to have and why
 
HTTP/2
HTTP/2HTTP/2
HTTP/2
 
The problem with the real world
The problem with the real worldThe problem with the real world
The problem with the real world
 
Total Cost of Pwnership
Total Cost of PwnershipTotal Cost of Pwnership
Total Cost of Pwnership
 
Defense in Depth Web Inkognito 12/2013
Defense in Depth Web Inkognito 12/2013Defense in Depth Web Inkognito 12/2013
Defense in Depth Web Inkognito 12/2013
 
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013Bezpečnost webových aplikací Web Inkognito VŠE 05/2013
Bezpečnost webových aplikací Web Inkognito VŠE 05/2013
 

Zabezpečení Slevomatu

  • 1. Jak jsme zlepšili zabezpečení Slevomat.cz Michal Špaček @spazef0rze www.michalspacek.cz Tyto slajdy obsahují poznámky nejen pro ty, kteří na přednášce nebyli.
  • 2. $this context→ Slevomat má ~1M zákazníků, v databázi ~1.8M uživatelských účtů a web slevomat.cz denně navštíví přes 200k návštěvníků. Slevomat v roce 2013 dosáhl miliardového obratu, má vlastní značku zboží i vlastní sklad. Ve Slevomatu pracuje 150 lidí, vývojové oddělení čítá 10 hlav, mezi nimi např. @kukulich, @vasekpurchart nebo @patrikvotocek. Nechceš se k nim přidat? Slevomat používá PHP 5.5, Nette 2.1, Elasticsearch a MySQL resp. Percona Server, který obslouží ~2.5M dotazů za hodinu. Čísla kreditních karet nejsou uložena v databázi Slevomatu, pamatuje si je platební brána. Uživatelé mohou na svých účtech mít kredity, kterými mohou platit, ale nedají se převádět na jiného uživatele. Aktualizace: všechny informace na tomto slajdu jsou z roku 2014 a mohou se od aktuálního stavu lišit.
  • 3. Dříve bylo možné se přihlásit z jakékoliv stránky – po kliknutí na tlačítko vpravo nahoře se rovnou objevil přihlašovací formulář a to i přesto, že stránka přišla po nezabezpečeném HTTP. Formulář se sice odesílal šifrovaně pomocí HTTPS, ale mohl být po cestě do prohlížeče změněn tak, aby se odesílal někam úplně jinam. Přihlašování jsme tedy přesunuli na samostatnou stránku, která se stahuje po HTTPS, obsah formuláře tedy do prohlížeče dorazí v původním stavu.
  • 4. Web slevomat.cz zatím neběží celý na HTTPS (update: od července 2014 již ano), takže ačkoliv se případný mizera nedostane k přihlašovacím údajům změnou formuláře po cestě, může se odposlechem dostat k session id cookie, protože ta se přenáší i po nezabezpečeném HTTP. Až bude celý web přístupný pouze po HTTPS, cookie označíme jako Secure a tím zajistíme, že se bude přenášet jen po šifrovaném HTTPS a nepůjde odposlechnout. Direktivy session.cookie_httponly a session.use_only_cookies pro obranu před útoky na session máme samozřejmě zapnuté už docela dlouho. session.cookie_secure
  • 5. Při relativně velké zátěži webových serverů Slevomatu nechceme přechod na zabezpečené HTTPS udělat najednou, ale raději postupně přesunujeme jednotlivé části webu. Velmi brzy bude celý web přístupný jen a pouze přes HTTPS. A pak zas můžeme vrátit přihlašovací formulář do Lightboxu na každou stránku.
  • 6. HTTP Strict Transport Security Strict-Transport-Security: max-age=31536000; includeSubDomains Až bude celý web přístupný pouze pomocí HTTPS, budeme posílat hlavičku Strict-Transport-Security, která zajístí to, že se prohlížeč ani nebude pokoušet server kontaktovat po HTTP a rovnou bude po stanovenou dobu všechny odkazy sám převádět na HTTPS. Zabráníme tím man-in-the-middle útokům, které převádějí šifrované HTTPS spojení na obyčejné HTTP. Hlavičku podporuje většina moderních browserů, IE ji bude podporovat od verze 12.
  • 7. Přenos hesel a session ids tedy bude zabezpečen docela dobře. K uživatelským údajům se ale dá dostat i jinak, než odposlechem. Třeba tak, že jednoho krásného dne najdete na serveru 12 GB záloh cizích databází, protože je tam někdo kdysi nahrál a nesmazal. Opravdu se to stává a je lepší počítat s tím, že i vaše databáze se může někde objevit.
  • 8. $dibi →select('jmeno') where(→ "id = $_GET[id]"); Ale nemusí to být jenom zálohy na nepatřičných místech. Firemní údaje a hesla uživatelů se z databáze dají vysosat třeba úspěšným provedením útoku SQL Injection. Spousta uživatelů používá jedno heslo na více místech a když z jednoho takového místa to heslo unikne, tak … raději nedomýšlet. A ano, SQL Injection lze provést i v Nette, Dibi a PDO, pokud se tyto nástroje použijí trochu nešikovně. Žádný nástroj automagicky nevyřeší zabezpečení webu.
  • 9. 8b8f05049b2114ad3d33 0db391e78549670d6b4b Slevomat dříve heslo před uložením zahashoval pomocí algoritmu SHA-1, aby nebylo tak jednoduché ho získat, pokud by se k databázi nějakým způsobem dostal někdo nepovolaný. Heslo nebylo saltované, takže nebylo chráněno proti tzv. narozeninovým útokům, ani proti použití předpočítaných tabulek. Jenže ty se už dnes stejně moc nepoužívají, hesla se crackují hrubou silou, slovníkovými nebo hybridními útoky. Každý obyčejný laptop umí spočítat desítky miliónů SHA-1 hashů za vteřinu a moderní grafické karty jsou stokrát rychlejší. Cracknout takové běžné heslo hashované SHA-1 je tedy otázkou maximálně pár minut a ani salt by crackování nezpomalil. Zkuste si to sami pomocí nástroje oclHashcat.
  • 10. cHJvZDE=;GwEuCSSgBCL x0BHHAAb8IA==;kvmDV/ DEJ3H+how7bErLa+/xap V2282MmISXqVo8xREfnB KcNmAixIaDDnYkODCu9K W3+6sbM04W7Tm3w1S+NQ== Nyní Slevomat ukládá hesla tak, že heslo zahashuje relativně pomalým algoritmem bcrypt, aktuálně s cost parametrem 10. Výsledný hash se navíc zašifruje pomocí AES-256-CBC a poté se uloží do databáze. Je to klacek pod nohy, pravděpodobnost, že se mizera dostane k databázi a zároveň ke konfiguračnímu souboru aplikace, ve kterém je uložen šifrovací klíč, je mnohem menší, než že se dostane jenom k databázi. A pokud získá databázi i klíč, tak po rozšifrování má před sebou pořád ty bcrypt hashe. Výše je mé aktuální heslo tak, jak je uloženo v produkční databázi Slevomatu. Všimněte si id klíče, inicializačního vektoru a šifrovaného hashe, vše odděleno středníkem a zakódováno do Base64.
  • 11. password_hash(…, PASSWORD_DEFAULT) ircmaxell/password_compat Pro pouhé hashování hesel algoritmem bcrypt použijte funkci password_hash() a pro ověření password_verify(). Tyto funkce jsou dostupné až od PHP 5.5, ale pro starší PHP (od PHP 5.3.7) existuje knihovna password_compat, která tyto funkce implementuje v čistém PHP. Najdete ji na GitHubu nebo ji můžete nainstalovat pomocí Composeru. Jednoduchý příklad použití najdete u mě na GitHubu na https://github.com/spaze/encrypt-hash-password-php v souboru example-hash.php.
  • 12. mcrypt_encrypt() MCRYPT_RIJNDAEL_128 Pro následné šifrování hashů hesel pomocí AES-256 v PHP použijte funkce mcrypt_encrypt() a mcrypt_decrypt() z rozšíření mcrypt. Aktualizace: mcrypt je depracated od PHP 7.1, použijte raději na konci odstavce zmiňovanou knihovnu defuse/php-encryption. Bloková šifra AES je variantou šifry Rijndael s velikostí bloku 128 bitů, použijeme tedy konstantu MCRYPT_RIJNDAEL_128. Hodnota 256 v názvu znamená velikost použitého šifrovacího klíče v bitech. Pro ukládání hashů je vhodný režim CBC (Cipher-block chaining), ten při volání mcrypt_encrypt() zvolíme pomocí MCRYPT_MODE_CBC. Inicializační vektor vytvoříme funkcí mcrypt_create_iv() s parametrem MCRYPT_DEV_URANDOM. Jednoduchý příklad najdete opět na GitHubu: https://github.com/spaze/encrypt-hash-password-php v souboru example-encrypthash.php. Pro obecné šifrování dat raději použijte knihovnu https://github.com/defuse/php-encryption, která přidává autentizaci zašifrovaných dat pomocí metody Encrypt-then-MAC.
  • 13. aes(bcrypt(sha1(…))) aes(bcrypt(…)) Ve Slevomatu jsme chtěli zabezpečit i hesla uživatelů, kteří se dlouho nepřihlásili. Vzali jsme tedy stávající SHA-1 hashe, zahashovali bcryptem a pak zašifrovali AES- 256. Taková hesla jsme si označili, abychom při ověřování věděli, že z hesla zadaného uživatelem máme nejdříve udělat SHA-1 hash a až pak s ním pracovat dále. Když se takový uživatel úspěšně přihlásí, tak zadané heslo v čitelné podobě zahashujeme jen bcryptem s vynecháním SHA-1, hash zašifrujeme a výsledek uložíme do databáze. To děláme i při nastavení hesla nového. Mezikrok s SHA-1 je lepší, než vynucená změna hesla všech uživatelů, je ale zbytečný a pokud můžeme, tak ho odstraníme.
  • 14. bcrypt(token) Pomocí funkce password_hash() hashujeme i tokeny pro semi-permanentní přihlášení i pro přihlášení pomocí Facebooku. V čitelné podobě je v databázi nemáme. Token z cookie pak ověřujeme stejně jako heslo při přihlašování, tedy funkcí password_verify(). Hash tokenu v databázi nalezneme podle identifikátoru uživatele z cookie. Aktualizace: tokeny jsou na rozdíl od běžných hesel náhodně generované a dlouhé minimálně 20 bajtů, pro uložení by tedy stačilo použít funkci hash('sha256', $token) a pro ověření funkci hash_equals().
  • 15. Funkci Zapomenuté heslo máme vyřešenu tak, že uživateli posíláme odkaz, který obsahuje token, jehož platnost je časově omezena – momentálně na 30 minut od odeslání odkazu. Tento interval by neměl přesáhnout 60 minut. E-mail nově obsahuje i odkaz pro zneplatnění tokenu. Token hashujeme bcryptem, v databázi není uložen v čitelné podobě. Zákaznické podpoře jsme odebrali možnost nastavovat hesla uživatelům v administraci Slevomatu, ale pro některé domény jsme tuto možnost museli vrátit zpět. Centrum.cz totiž doručuje některé e-maily s mnohahodinovým zpožděním a uživatel tak prošvihne interval, během kterého je token platný a o pomoc pak žádá právě zákaznickou podporu.
  • 16. Vaše heslo je: ••••• Hesla nově nikdy neposíláme e-mailem, ani při registraci. Veškeré změny logujeme a víme kdo, kdy a z jaké IP adresy změnil heslo nebo e-mailovou adresu. Uživatele po změně informujeme, pro jistotu. Brzy chceme změnit politiku vytváření hesel, současné omezení na min. 5 znaků je dnes již nevyhovující. Nová hesla by měla mít minimálně 8 znaků. Maximální povolená délka hesla je 4096 znaků, delší hesla příliš zatěžují server při hashování bcryptem. Aktualizace: implementace bcryptu v PHP delší hesla automaticky ořezává na 72 znaků, toto omezení je na Slevomatu nadbytečné.
  • 17. Content Security Policy Ve Slevomatu používáme šablonovací systém Latte, který je součástí Nette Frameworku. Latte automagicky ošetřuje vypisované proměnné, ale i přesto se může stát, že uděláte chybu, třeba při tvorbě vlastních maker, a váš web bude zranitelný pomocí útoku Cross-Site Scripting (XSS). Ke snížení dopadu případného úspěšného útoku bude Slevomat brzy posílat HTTP hlavičku Content-Security- Policy, která vyjmenovává zdroje (whitelisting), odkud může prohlížeč do stránky vkládat obrázky, kaskádové styly, JavaScript a další. Browser nebude spouštět ani inline JavaScript, pokud se pošle i hodnota 'unsafe-inline', JavaScriptový kód pak musí být v externích souborech. Na přesunu pilně pracujeme.
  • 18. <script> var foo = 123; var color = 'purple'; </script> Posílat hodnotu 'unsafe-inline' rozhodně chcete, zakázáním spouštění JavaScriptu vloženého přímo do stránky zabráníte úspěšnému provedení útoku Cross-Site Scripting i kdyby někdo nějak do stránky nějaký JavaScript vložil. Občas se přímo do stránky úmyslně vkládá nějaká konfigurace, ovšem pokud je to uděláno výše uvedeným způsobem, tak to přestane fungovat. S 'unsafe-inline' momentálně nefunguje ani kód Google Tag Manageru, a to ani s využitím experimentální podpory nonce-source z připravované specifikace CSP 1.1 v Chrome 35. Slevomat používá Google Tag Manager a 'unsafe-inline' je pro nás tedy momentálně nepoužitelné.
  • 19. <script id="conf" type="text/json"> { "foo" = "123", "color" = "purple" } </script> <script src="code.js"></script> Konfiguraci ve stránce je možné zachovat, jen je potřeba změnit typ obsahu značky SCRIPT na text/json. JSON není kód, nelze spustit a browser ho tedy při 'unsafe-inline' nemusí blokovat. V code.js se pak k hodnotám dostanete takto: var c = document.getElementById('conf'); var d = JSON.parse(c.textContent || c.innerHTML);.
  • 20. $c = stream_context_create(array( 'ssl' => array( 'verify_peer' => true, 'verify_depth' => 9, 'cafile' => $caFile, 'disable_compression' => true, ) )); Pokud potřebujeme komunikovat s nějakým API, používáme k tomu šifrovaný protokol HTTPS. Pro bezpečnou komunikaci musíme také ověřovat, že opravdu komunikujeme třeba s bankou a že to není nějaký mizera, který se za banku vydává. Vypnutím TLS komprese se pak bráníme proti útoku CRIME. Takto bude defaultně nastaveno i PHP 5.6+.
  • 21. JDE TO! www.michalspacek.cz V zabezpečování Slevomatu a uživatelských dat budeme samozřejmě pokračovat dále, ještě nás čeká spousta práce, ale když se chce, tak to jde. Snad jsem vás také trochu inspiroval a pokud byste chtěli se zabezpečením webů a aplikací pomoci, napište mi, rád pomohu. Kontakty jsou uvedeny na mém webu. Díky!