Bezpečnost PHP pro podnikový web

Josef

Bezpečnost PHP pro podnikový web
« kdy: 10. 07. 2014, 11:49:04 »
Ahoj,

chystam se udelat takovou malou stranku, kde klientum budu rikat rekneme informace treba o stavu jejich pozadavku k vyrizeni, taky treba kolik maji na nasem ucte jeste kreditu apod.

Jelikoz PHP je celkem snadne na porozumeni, chtel jsem se zeptat zkusenych programatoru:

A) je prihlaseni pomoci session bezpecne?
B) je bezpecne ukladat promenou treba jako ses_admin? v session?
C) jako ochranu proti odcizeni session jsem udelal funkci pro kontrolu IP adresy, jestli se zmeni je session znicena.
D) je mysql_real_escape_string dostatecny proti injekci kodu?
E) hesla klientu pro prihlaseni ukladam pomoci hashe

« Poslední změna: 10. 07. 2014, 22:24:43 od Petr Krčmář »


podhy

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #1 kdy: 10. 07. 2014, 12:23:12 »
A) ano je ale pouze pokud si ošetříte další bezpečnostní hrozby (XSS, CSRF, atd.)
B) ano (viz bod A)
C) nedostatečné (je potřeba mít dobře nastavené hlavně php.ini). Co uživatelé s dynamickými IP adresami?
D) měla by být, ale lepší je používat prepared statements
E) je to dostatečné, ale v závislosti na použitém algoritmu (MD5 ani SHA1 pro ukládání hesel bezpečné nejsou)

whata

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #2 kdy: 10. 07. 2014, 12:28:47 »
Ty dotazy nejsou příliš specifické na PHP.

A) Přihlašuje se pomocí uživatele a hesla, session je jen prostředek a je tak bezpečený, jak je bezpečný přístup k serveru :-) Není vhodné posílat session id jako query parameter.

B) Cokoliv kromě hesla.

C) Zbytečnost (NAT) a kontraproduktivní (v případě proxy clusteru se adresa měnit může).

D) Escapování je specifické pro SQL dialect. Vhodnější jsou bind variables. Pokud už escapování, mělo by být součástí abstrakce nad connection.

E) Vhodné přidat salt nebo třeba username, aby dva uživatelé se stejným heslem neměli stejný hash.

randomek

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #3 kdy: 10. 07. 2014, 12:33:08 »
A) muzes to vylepsit treba zaslanim jednorazoveho kodu na mobil (jako v internet bankingach). Samozrejmosti by melo byt pouziti HTTPS
B) je, ale to nezarucuje, ze se vlivem tebou nasaneho spatneho kodu obsah te promenne nejak nezmeni nebo nedostane ven. Urcite bych pouzil
nejaky framework, kde jsou tyhle veci dobre osetrene a je to provereno x uzivately
C) spousta lidi maji sdilenou IP. Urcite bych sesssion regeneroval pri kazde nejake dulezitejsi operaci
D) ajajaj a co PDO?
E) SHA1

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #4 kdy: 10. 07. 2014, 12:42:17 »
A) je prihlaseni pomoci session bezpecne?
Čemu říkáte "přihlášení pomocí session"? Myslíte přihlášení pomocí webového formuláře a následné uložení informace o přihlášeném uživateli do session? Je to skoro ten nejméně bezpečný způsob přihlášení, ale zároveň je nejpoužívanější, protože podpora bezpečných způsobů přihlášení je v prohlížečích mizerná a uživatelsky nepřátelská.
Záleží jednak na tom, jak bezpečně přenesete údaje zadané ve formuláři, a také na tom, jak bezpečný je identifikátor session. Pokud jej přenášíte v URL, uteče v referreru s každým odkazem na jiný server (i třeba stažení obrázku nebo reklamy odjinud). Pokud je v cookie, přečte jej "jenom" ten, kdo vidí nešifrovaný obsah komunikace, případně - pokud nemá nastaven příznak HTTP only, vidí ji každý skript ve stránce.

B) je bezpecne ukladat promenou treba jako ses_admin? v session?
Celé je to závislé na tom, jak je bezpečný identifikátor session. Samozřejmě je nutné tu proměnnou číst skutečně jen ze session, nepoužívat přiřazení globálních proměnných, kde se ta proměnná může vzít skoro odkudkoli (takže jí útočník může podstrčit).

C) jako ochranu proti odcizeni session jsem udelal funkci pro kontrolu IP adresy, jestli se zmeni je session znicena.
Nejsem si jist, zda to neudělá víc škody než užitku. Celé velké sítě jsou schované za NATem s jednou IP adresou, zároveň se IP adresa uživatele může měnit, aniž by to mohl ovlivnit. Pokud jej budete pořád odhlašovat (a pokud možno ještě tak, že vždy přijde o rozdělanou práci), asi se na váš web brzy vykašle.

D) je mysql_real_escape_string dostatecny proti injekci kodu?
Sám o sobě určitě ne, záleží na tom, jak s ním pracujete a zda jej použijete všude, kde je to potřeba. Což se těžko kontroluje. A také na tom, zda parsuje SQL dotazy přesně stejně, jako použitá knihovna pro MySQL. Pokud nemáte velmi vážný důvod proti, použijte raději binding proměnných.

E) hesla klientu pro prihlaseni ukladam pomoci hashe
Před hashováním hesla k tomu heslu určitě něco přidejte. Buď alespoň konstantu (např. název serveru), nebo lépe sůl - něco náhodného unikátního pro každé heslo (sůl si pak samozřejmě musíte zapamatovat spolu s hashem).

Jinak ale zabezpečení se nedá udělat tak, že zkontrolujete pár věcí, o jejichž nebezpečnosti jste slyšel. Je potřeba se na bezpečnost dívat komplexně a myslet na ní neustále, jinak zkontrolujete jednu věc a vedle necháte díru jak vrata.


Jimm

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #5 kdy: 10. 07. 2014, 15:00:14 »
Vzhledem k technické úrovni dotazů bych odpověděl stručně: Může to být bezpečné a v technologii problém není, ale vy to bezpečně nenapíšete. Nestačí otevřít příručku a napsat podle ní bankovnictví...

Josef

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #6 kdy: 10. 07. 2014, 16:27:46 »
Vzhledem k technické úrovni dotazů bych odpověděl stručně: Může to být bezpečné a v technologii problém není, ale vy to bezpečně nenapíšete. Nestačí otevřít příručku a napsat podle ní bankovnictví...

No nikdo nerikal, ze sem expert  a bohuzel vsichni nemuzeme byt tak dokonaly... Nic mene dekuju za prispevky :)

CyberBob

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #7 kdy: 10. 07. 2014, 16:27:57 »
D.)
function sanitize($input){
        $input = htmlentities($input); // convert symbols to html entities
        $input = addslashes($input); // server doesn't add slashes, so we will add them to escape ',",\,NULL
        $input = mysql_real_escape_string($input); // escapes \x00, \n, \r, \, ', " and \x1a
        return $input;
}

Kit

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #8 kdy: 10. 07. 2014, 17:01:20 »
D.)
function sanitize($input){
        $input = htmlentities($input); // convert symbols to html entities
        $input = addslashes($input); // server doesn't add slashes, so we will add them to escape ',",\,NULL
        $input = mysql_real_escape_string($input); // escapes \x00, \n, \r, \, ', " and \x1a
        return $input;
}

To má být vtip?

Pleca

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #9 kdy: 10. 07. 2014, 17:24:24 »
D) lepsi pouzit PDO
E) hashovat pomoci password_hash http://docs.php.net/manual/en/function.password-hash.php
zadane heslo portovnavat s hashem pomoci password_verify http://docs.php.net/manual/en/function.password-verify.php

j

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #10 kdy: 10. 07. 2014, 17:51:40 »
ad DB: na escapovani bych se rozhodne nespolejhal, vetsinou tak jako tak prenasis nejaky predem ocekavany parametry => zkontrolovat je driv nez snima vubec zacnes pracovat (ze cislo je skutecne cislo ... ze je v ocekavanym rozsahu ....). Ano, neni to moc v mode, protoze je to prace navic. Jinak jak bylo receno, prepared statements.

ad pass: Samotny hash neni moc dobry napad, zalezi jak moc bezpecny pristup chces a co useri snesou. Moznosti je spousta, kazdopadne pokud jen trochu muzes, nepouzivej na prenos hesel formulare. Mozna to nebude vypadat "hezky", ale bude to bezpecnejsi. Taky se vyvaruj kombinaci http/https ... je to presne totez, jako kdyz pouzijes jen http.

As sessions/cookies ... obecne cim min toho u usera ukladas, tim lip. Databaze tech par dat unese a nic jinyho nez nejakou identifikaci nepotrebujes. Ipcka vubec neres, jak bylo receno, nadelas si vic problemu nez uzitku. Asi bych te zabil, kdybys me co 10 mitut odhlasil protoze se mi v ramci privacy ext zmeni IP ... muzes taky zkusit vyuzit html5 databazi.

M.

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #11 kdy: 10. 07. 2014, 18:15:00 »
Pokud by šlo o vnitropodnikovou aplikaci. Není z dotazu úplně zřejmé, co je myšleno malou podnikovou aplikací, tak bych ověřování v PHP vůbec neřešil. Děláme to metodou SSO, kdy ověření dělá přímo Apache webserver pomocí kerberosu proti doménovému řadiči (ať už Windows server nebo Samba4). Klient má v prohlížeči jen povoleno, že to má používat pro svoje domény a PHP jen dostane rovonu ověřenou informaci, že má tu čest s jmeno@DOMENA.NĚCO. Pro vnitrpodnikové řešení příjemné pro obě strany, klienta to autoamticky přihlásí tím, očím je přihlášen k počítači a PHP apliakce jen hotový výsledek, který si slinkuje s nějakými daty v DB (nebo LDAPu)...

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #12 kdy: 10. 07. 2014, 18:37:29 »
D.)
function sanitize($input){
        $input = htmlentities($input); // convert symbols to html entities
        $input = addslashes($input); // server doesn't add slashes, so we will add them to escape ',",\,NULL
        $input = mysql_real_escape_string($input); // escapes \x00, \n, \r, \, ', " and \x1a
        return $input;
}
Tohle je krásný příklad, proč escapování nepoužívat. Vnutíte programátorům takovouhle funkci, ta escapování udělá pokaždé špatně, programátor si bude myslet, že se escapování volá dvakrát, tak svoje volání odstraní, a hned máte v kódu bezpečnostní díru.
Escapování se používá vždy tam, kde mají příslušné znaky speciální význam. Takže htmlentities() se použije pří výstupu do HTML, mysql_real_escape_string(), pokud už by se použilo, se použije při vstupu do databáze, takže tyhle dvě funkce se nikdy nemůžou aplikovat o sobě, nedává to žádný smysl. A to addslashes() už je jenom bonbónek na závěr, aby ta funkce byla zmatlaná pořádně.

Jenda

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #13 kdy: 11. 07. 2014, 00:12:50 »
E) hashovat pomoci password_hash http://docs.php.net/manual/en/function.password-hash.php
zadane heslo portovnavat s hashem pomoci password_verify http://docs.php.net/manual/en/function.password-verify.php
Líbí se mi, jaké všechny rovnáky na vohejbáky lidé vymyslí a kolik času tím stráví místo aby implementovali jeden z mnoha jednoduchých existujících protokolů, které heslo na druhou stranu vůbec přenášet nepotřebují.

Jenda

Re:PHP - bezpecnost pro maly podnikovy web
« Odpověď #14 kdy: 11. 07. 2014, 00:14:50 »
E) hashovat pomoci password_hash http://docs.php.net/manual/en/function.password-hash.php
zadane heslo portovnavat s hashem pomoci password_verify http://docs.php.net/manual/en/function.password-verify.php
Líbí se mi, jaké všechny rovnáky na vohejbáky lidé vymyslí a kolik času tím stráví místo aby implementovali jeden z mnoha jednoduchých existujících protokolů, které heslo na druhou stranu vůbec přenášet nepotřebují.