Bezpečná session v PHP

Re:Bezpečná session v PHP
« Odpověď #15 kdy: 17. 03. 2020, 15:12:03 »
Co je špatně na $_SESSION „z devadesátkých let“ pokud používám vynucené https? IMHO je to pro řadu případů zcela dostačující řešení. Spíš bych si dal pozor na SQL injection při zadávání jména a hesla.

Posílat heslo po HTTPS považuji za zbytečné, když může práci provést klient. Aplikace heslo nemusí nikdy znát a nikdy obdržet. Sníží se tím riziko MITM útoku na HTTPS. V devadesátých letech byla ještě spousta užití a prohlížečů, které JS implementovaly všelijak, takže se vše provádělo server side, mělo to racionální důvod. Dnes ten důvod už neexistuje a jede se jen ze setrvačnosti. Pan kolega se ptal na bezpečnost, tak k tomu směřovala odpověď.

Na SQL injections je opravdu potřeba si dát pozor, vždy a v každém případě!

Samozřejmě v principu máte pravdu a je bezpečnější, aby server heslo neznal. Ale pro tazatele je důležité, aby pochopil základ, což je v daném usecase:

  • pochopit princip session a její použití v PHP
  • pochopit význam vynuceného https a zasílání dat metodou POST
  • pochopit význam soleného hashování při ukládání hesla do databáze
  • pochopit a zamezit sql injection

Teprve při zvládnutí tohoto má podle mě cenu zvednou laťku a nasazovat javascript.


Re:Bezpečná session v PHP
« Odpověď #16 kdy: 17. 03. 2020, 15:15:26 »
Super. Díky za nápovědu.
Ještě se zeptám. Ošetřuje se nějak situaci kdy má klient vypnuté cookies? Jak se pak chová server? Na základě čeho ověří že se jedná o daného uživatele.

Když to shrnu do bodů
a) na serveru je stránka s logováním
b) uživatel načte stránku + zadá jméno a heslo
c) odešle formulář (pomocí post?)
d) na serveru z post získám jméno + heslo (nevím jestli je tohle bezpečné nebo už tady je něco špatně?). Heslo se nějak musí dostat z formuláře klienta na můj server. Nevím jak je toto bezpečné.
e) na serveru ověřím uživatele a pokud je ok, pošlu mu sessionid (náhodně generované kvůli únosu a nebo sekvenčně pokud použiju jwt)
f) klient má id uložené v cookie? a při každém dotazu jej z cookie načte a pošle mi jej?


Pokud bych se vykašlal na cookie můžu mít to id uložené jen někde v paměti ? Nepotřebuju aby session zůstávala třeba 10 hod aktivní. Nedělám eshop, takže pokud uživatel zavře tab a otevře jiný nový, klidně jej donutím znova se přihlásit. Nebude to zas až tak častá aktivita (předpokládám).

Taky jsem četl, že pro bezpečnější web je dobré u kritických operací sessionid zahodit, vygenerovat nové a nechat uživatele znova ověřit (pro jistotu, aby bylo jisté že se nejedná o podvrh). Takže pokud bych narazil na jějakou kritickou část (například změna hesla), můžu to klidně udlěat i takto.

Pokud nastavíte https://www.php.net/manual/en/session.configuration.php#ini.session.auto-start na true tak bude session v PHP fungovat úplně automaticky. Do session zapíšete kdykoli prostým vložením hodnoty do pole $_SESSION a údaje získáte naopak čtením ze $_SESSION. Session id si PHP uloží automaticky do cookies v prohlížeči, takže bude PHP schopné při každém requestu ztotožnit požadavek prohlížeče s příslušnou session na serveru. Životnost session bude PHP také hlídat automaticky. Pokud bude web nastaven tak, aby běžel vynuceně na https, je to i relativně bezpečné. Je lepší se spolehnout na toto hotové řešení přítomné v PHP než se snažit si session implementovat jinak - šance, že uděláte při vlastní implementaci chybu, je značná.

Do $_SESSION si uložíte cokoli potřebujete, typicky identifikátor přihlášeného uživatele. Takže při prvním přihlášení ověříte přítomnost jména a hesla v databázi (budete hledat v databázi hash hesla, aby tam nebyla hesla uložena v čitelné podobě) a při úspěchu si uložíte identifikátor uživatele do $_SESSION. Při dalších požadavcích kontrolujete přítomnost identifikátoru v $_SESSION a přítomnost uživatele v databázi. Pokud bude nalezen, je přihlášen, pokud nikoli, není přihlášen. Při odhlášení zrušíte nejlépe celou session https://www.php.net/manual/en/function.session-destroy.php

Při zadávání jména a hesla dejte pozor na SQL injection, nejlepší je použít hotovou knihovnu. Stačí použít prepared statements v PDO případně nadstavby PDO. PDO měla také nějaké zranitelnosti, aktuální stav ale neznám, takže mě případně někdo doplní (IMHO při použití současných verzí Mysql a PHP je to již vyřešeno).

Re:Bezpečná session v PHP
« Odpověď #17 kdy: 17. 03. 2020, 15:55:17 »
Teprve při zvládnutí tohoto má podle mě cenu zvednou laťku a nasazovat javascript.

Nevím, to je podle mě jako učit ve škole psát na stroji a k počítači až za zásluhu. Moje zkušenost velí učit programátory pochopit potřebné technologie, ale to je asi věc názoru.

Re:Bezpečná session v PHP
« Odpověď #18 kdy: 17. 03. 2020, 15:56:47 »
Pokud nastavíte https://www.php.net/manual/en/session.configuration.php#ini.session.auto-start na true tak bude session v PHP fungovat úplně automaticky.

To bych nedělal. Podle nařízení EU i podle české legislativy musí být cookie formou opt-in. Zatím se to přechodně porušuje (různé cookie bary často nastaví cookie dřív, než návštěvník odsouhlasí). Ale není to rozhodně dobrá rada pro nový projekt.

Re:Bezpečná session v PHP
« Odpověď #19 kdy: 17. 03. 2020, 16:16:20 »
Teprve při zvládnutí tohoto má podle mě cenu zvednou laťku a nasazovat javascript.

Nevím, to je podle mě jako učit ve škole psát na stroji a k počítači až za zásluhu. Moje zkušenost velí učit programátory pochopit potřebné technologie, ale to je asi věc názoru.

Jasně, nic proti, didaktika je do značné míry subjektivní disciplína (a u každého funguje trochu jinak).


Re:Bezpečná session v PHP
« Odpověď #20 kdy: 17. 03. 2020, 16:26:26 »
Předpokládám, když se ptá, že chce získat přehled, jaké jsou možnosti.
Tak příště radši nepředpokládejte a místo toho čtěte zadání. maw abi nechce znát možnosti, chce se dozvědět úplné základy.

To, co popisujete, je možná nejpoužívanější, ale dnes už je jasné, že je to překonané a budoucnost si s tím nevystačí.
Jenže to budou implementovat lidé, kteří alespoň trochu vědí, o čem je řeč. Ne někdo,kdo se právě začal učit PHP. Hashovat heslo už v prohlížeči je teoreticky samozřejmě správně, ale když to bude implementovat někdo, kdo tomu vůbec nerozumí, bude výsledek milionkrát nebezpečnější, než když heslo standardně odešle POSTem přes HTTPS a na serveru zahashuje přes password_hash(). Což tazatel samozřejmě vědět nemůže, ale vy byste to vědět měl, když chcete radit.

Rozhodnutí je samozřejmě na tazateli, nemůžeme tu posoudit o jak citlivá data jde, jestli hrozí riziko finančních škod atd.
Pokud jste z dotazu nepochopil, že maw abi v žádném případě nemá kvalifikaci na to, aby tohle dokázal posoudit, raději nikdy nikomu nic neraďte. Že to maw abi nedokáže posoudit je naprosto v pořádku, začíná se v problematice zorientovávat. Špatné je to, jaké nesmysly píšete vy.

Nevím, to je podle mě jako učit ve škole psát na stroji a k počítači až za zásluhu. Moje zkušenost velí učit programátory pochopit potřebné technologie, ale to je asi věc názoru.
Ne, to není věc názoru. To je věc toho, že absolutně nedokážete rozumně poradit. Vy jste nikomu nepomohl pochopit nějaké technologie – akorát jste někomu zamotal hlavu, a po několikátém upozornění z vás teprve vypadlo, že aby to mohl maw abi posoudit, musel by mít takové znalosti, že by radil on vám a ne vy jemu.

To bych nedělal. Podle nařízení EU i podle české legislativy musí být cookie formou opt-in. Zatím se to přechodně porušuje (různé cookie bary často nastaví cookie dřív, než návštěvník odsouhlasí). Ale není to rozhodně dobrá rada pro nový projekt.
Souhlas s použitím cookies ovšem uživatel dává nastavením prohlížeče.

Re:Bezpečná session v PHP
« Odpověď #21 kdy: 17. 03. 2020, 16:29:11 »
Pokud nastavíte https://www.php.net/manual/en/session.configuration.php#ini.session.auto-start na true tak bude session v PHP fungovat úplně automaticky.

To bych nedělal. Podle nařízení EU i podle české legislativy musí být cookie formou opt-in. Zatím se to přechodně porušuje (různé cookie bary často nastaví cookie dřív, než návštěvník odsouhlasí). Ale není to rozhodně dobrá rada pro nový projekt.

Při registraci a přihlášení musí uživatel tak jako tak nějaké své údaje předat a tedy musí být již GDPR ošetřené. Bez poskytnutí dat není možné službu vůbec poskytovat, je to nutná podmínka.

Ale ano, teoreticky bude lepší session nastartovat až dle potřeby, i třeba z hlediska výkonu apod. Takže pokud není session nastarovaná, tak ji nastartovat až při přihlášení, viz https://www.php.net/manual/en/function.session-status.php a https://www.php.net/manual/en/function.session-start.php

Re:Bezpečná session v PHP
« Odpověď #22 kdy: 17. 03. 2020, 16:32:46 »
To bych nedělal. Podle nařízení EU i podle české legislativy musí být cookie formou opt-in. Zatím se to přechodně porušuje (různé cookie bary často nastaví cookie dřív, než návštěvník odsouhlasí). Ale není to rozhodně dobrá rada pro nový projekt.
Souhlas s použitím cookies ovšem uživatel dává nastavením prohlížeče.

Zajímavé, já to rovnou z https://www.uoou.cz/assets/File.ashx?id_org=200144&id_dokumenty=37240 ocituji:
Citace
Uživatel určuje v nastavení svého PC, resp. v nastavení prohlížeče, zda má prohlížeč umožnit webovské stránce ukládat cookies do koncového zařízení. Toto nastavení lze považovat za souhlas se zpracováním osobních údajů.Prohlížeč je nástrojem zprostředkování souhlasu. Souhlas však nemůže zhojit jiné nedostatky, resp. nezákonnosti zpracování osobních údajů.

Ale je tam napsáno „návrh“, tak nevím jak je to se závazností...

Re:Bezpečná session v PHP
« Odpověď #23 kdy: 17. 03. 2020, 16:35:02 »
Souhlas s použitím cookies ovšem uživatel dává nastavením prohlížeče.

Poslal jste odkaz na návrh a jeho obsah je diskutovaný a diskutabilní a s nulovou právní hodnotou. V praxi mají prohlížeče cookies povoleny implicitně, nelze tedy hovořit o opt-in principu ani v přeneseném úkonu. Stále je to opt-out. Předpis má chránit uživatele a opt-in mechanismus je stanoven explicitně. Tedy, pokud máte jistotu, že to v prohlížeči zapnul ručně (opt-in), pak můžete přenést tento souhlas i na konkrétní situaci.

Pokud by tento návrh prošel legislativou, pak by nebylo co namítat, leč nyní nic takového nemáme. Zajímalo by mě, jak víc by měli v tom textu zdůraznit, že se nejedná o účinný dokument, než tím, že je tam jako kráva napsáno: "NÁVRH".

Re:Bezpečná session v PHP
« Odpověď #24 kdy: 17. 03. 2020, 16:55:51 »
Pokud se používá klasické session_id přes cookies u klienta, narazil jsem v minulosti na pokus převzít cizí aktivní session (ukrást a poslat její session_id).
Ošetřoval jsem to tak, že po úspěšném přihlášení a vytvoření session_id jsem zkombinoval session_id s IP adresou uživatele a uložil hash do databáze k uživateli - při každém přístupu pak hash z uvedených údajů znovu spočítal a kontroloval proti hodnotě v databázi - změna IP adresy uživatele pak znamená nový požadavek na přihlášení - vedlejší efekt je pak nefunkčnost přes Tor nebo jiné anonymizéry náhodně měnící IP adresu klienta.
Do kontrolního hashe lze také zahrnout (nebo použít místo IP adresy) otisk browseru použitého pro přihlášení (= inicializaci session).

Re:Bezpečná session v PHP
« Odpověď #25 kdy: 17. 03. 2020, 17:21:38 »
Pokud se používá klasické session_id přes cookies u klienta, narazil jsem v minulosti na pokus převzít cizí aktivní session (ukrást a poslat její session_id).

Při použití https vám session session nikdo (snadno) neukradne.

Re:Bezpečná session v PHP
« Odpověď #26 kdy: 17. 03. 2020, 17:27:30 »
Při použití https vám session session nikdo (snadno) neukradne.

Co třeba podnikové proxy servery s vlastními certifikáty, které přebíjejí ty původní?
Co třeba antiviry, které dělají to samé?
Co třeba malware, který může taky to samé udělat?

Těch cest je mnoho, můžeme diskutovat o tom, jak moc pravděpodobné jsou.
Každopádně tento směr úvah už je o tom, že PHP sessions jsou vetché a že na chatrných základech se nedá už opravdová bezpečnost lehce vyřešit.

Podle mě jde přijmout PHP sessions tak, jak jsou i s jejich nevýhodami a nepočítat s tím, že to půjde jednoduše refactorovat do něčeho novějšího. Nebo to rovnou postavit lépe, když ty technologie existují.

Re:Bezpečná session v PHP
« Odpověď #27 kdy: 17. 03. 2020, 17:32:15 »
Poslal jste odkaz na návrh a jeho obsah je diskutovaný a diskutabilní a s nulovou právní hodnotou.
Jasně, návrh doporučení ÚOOÚ má nulovou právní váhu, zatímco vyjádření všeuměla amatéra Miroslava Šilhavého ne nezpochybnitelné. Nechci vám brát iluze, ale o porušení podmínek bude případně rozhodovat ÚOOÚ, ne vy.

V praxi mají prohlížeče cookies povoleny implicitně, nelze tedy hovořit o opt-in principu ani v přeneseném úkonu. Stále je to opt-out. Předpis má chránit uživatele a opt-in mechanismus je stanoven explicitně. Tedy, pokud máte jistotu, že to v prohlížeči zapnul ručně (opt-in), pak můžete přenést tento souhlas i na konkrétní situaci.
No jo, oni se vás na to asi na ÚOOÚ zapomněli zeptat.

Pokud by tento návrh prošel legislativou, pak by nebylo co namítat, leč nyní nic takového nemáme. Zajímalo by mě, jak víc by měli v tom textu zdůraznit, že se nejedná o účinný dokument, než tím, že je tam jako kráva napsáno: "NÁVRH".
Příště si zkuste radši najít informace o tom dokumentu a neřídit se jedním slovem. Ten návrh je odkazován zde: Názory a rozhodnutí Úřadu: Cookies a GDPR. Nic novějšího nebo závaznějšího od té doby ÚOOÚ nevydal. Ano, je to jen návrh doporučení, ale vzhledem k tomu, že je autorem toho doporučení ÚOOÚ, dá se předpokládat, že to vyjadřuje názor ÚOOÚ a bude se tímto názorem řídit. Rozhodně je milionkrát pravděpodobnější, že se ÚOOÚ bude řídit tímhle, než že se bude řídit vašimi představami.

Re:Bezpečná session v PHP
« Odpověď #28 kdy: 17. 03. 2020, 17:36:06 »
Pokud se používá klasické session_id přes cookies u klienta, narazil jsem v minulosti na pokus převzít cizí aktivní session (ukrást a poslat její session_id).
Ošetřoval jsem to tak, že po úspěšném přihlášení a vytvoření session_id jsem zkombinoval session_id s IP adresou uživatele a uložil hash do databáze k uživateli - při každém přístupu pak hash z uvedených údajů znovu spočítal a kontroloval proti hodnotě v databázi - změna IP adresy uživatele pak znamená nový požadavek na přihlášení - vedlejší efekt je pak nefunkčnost přes Tor nebo jiné anonymizéry náhodně měnící IP adresu klienta.
Do kontrolního hashe lze také zahrnout (nebo použít místo IP adresy) otisk browseru použitého pro přihlášení (= inicializaci session).
Proto je potřeba dbát na to, aby identifikátor session nikam neunikl. Úniku při přenosu brání šifrování (HTTPS, cookie musí mít nastaven příznak Secure), je potřeba přenášet jej výhradně v cookie (ne v URL, kde by mohl uniknout do referreru nebo být přečten skriptem), pro cookie je potřeba nastavit HttpOnly (aby ji nešlo přečíst skriptem).

Vázání session na IP adresu se silně nedoporučuje, IP adresa klienta se může měnit. A naopak útočník může být za NATem ve stejné síti, jako uživatel.

Re:Bezpečná session v PHP
« Odpověď #29 kdy: 17. 03. 2020, 18:03:00 »
Jasně, návrh doporučení ÚOOÚ má nulovou právní váhu, zatímco vyjádření všeuměla amatéra Miroslava Šilhavého ne nezpochybnitelné. Nechci vám brát iluze, ale o porušení podmínek bude případně rozhodovat ÚOOÚ, ne vy.

To se bavíte ale o postihu stran správního práva. Druhou částí je i civilní žaloba, ve které názor ÚOOÚ nemá naprosto žádnou váhu.

Názory a rozhodnutí Úřadu: Cookies a GDPR[/url]. Nic novějšího nebo závaznějšího od té doby ÚOOÚ nevydal. Ano, je to jen návrh doporučení, ale vzhledem k tomu, že je autorem toho doporučení ÚOOÚ, dá se předpokládat, že to vyjadřuje názor ÚOOÚ a bude se tímto názorem řídit. Rozhodně je milionkrát pravděpodobnější, že se ÚOOÚ bude řídit tímhle, než že se bude řídit vašimi představami.

Právěže je to jen ve fázi návrhu. ÚOOÚ ví, že takto zatím nemůže postupovat. Kdyby takto mohl postupovat, pak by stačilo aby vyhláškou stanovil svůj postup. Každý úřad může vyhláškou stanovit mírnější úřední postup (např. tak to někdy dělá finanční správa). V tomto případě to udělat nemohou, protože by takový postup byl sice mírnější k provozovatelům webů, ale na druhé straně by tím zasahoval do zákonem daných práv uživatelů. Proto je to ve fázi návrhu a právě tato fáze vyjadřuje ten kontrast stavu jaký je a musí respektovat a stavu, jaký by navrhovali.

V Evropě je trend chránit soukromí. Nastavit cookie v 99 % případů není nezbytné a už vůbec ne u nového systému. Je to jen pohodlné a lacinější na vývoj. Tomu chce přesně EU zabránit. Myslím, že EU se neposadí na zadek z ÚOOÚ.