Autor | Zpráva | ||
---|---|---|---|
Kubas Profil * |
#1 · Zasláno: 6. 1. 2012, 00:08:46
Zdravím. Chtěl bych se zeptat zda- li je mnou udělané řešení bezpečné proti session hijacking a dalším útokům, případně byl bych velmi rád, kdyby mi někdo poradil, jak bezpečnostní díru vyřešit. Děkuji za reakce
login <?php include "config.php"; $login = mysql_real_escape_string($_POST["nick"]); $heslo = mysql_real_escape_string($_POST["heslo"]); $SHA1heslo = sha1($login.$heslo); $dotaz = mysql_query("select * from uzivatele where login = '$login' and heslo = '$SHA1heslo'"); $overeni = mysql_num_rows($dotaz); $row = mysql_fetch_array($dotaz); if($overeni == 1) { session_start(); $_SESSION['login'] = stripslashes($login); $_SESSION['id'] = $row["id"]; header("Location: prihlasen.php"); die(); } else { echo"Asi tu nemáš co dělat.."; } ?> Na login se ptám scriptem <form action="login.php" method="post"> <input type="text" name="nick" value=""> <input type="password" name="heslo" value=""> <p align="center"><input type="submit" type="submit" name="submit" value="Přihlásit"></p> </form> Ve scriptech pak používám dotaz na session <?php session_start(); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <?php if($_SESSION['login']){ $login = $_SESSION['login']; $id = $_SESSION['id']; . . Tu nějaký html nebo php script . . } else { echo'Asi tady nemáte co dělat..'; } ?> </body> </html> |
||
SeparateSK Profil |
#2 · Zasláno: 6. 1. 2012, 08:35:24
$_SESSION['login'] = base64_encode(stripslashes($login)); $_SESSION['id'] = base64_encode($row["id"]); $login = base64_decode($_SESSION['login']); $id = base64_decode($_SESSION['id']); |
||
blaaablaaa Profil |
#3 · Zasláno: 6. 1. 2012, 08:53:31
SeparateSK:
A proc by mel pouzivat base64? Jinak proti session hijackingu pouzij napr jeste kontrolu prohlizece apod. Misto "select * from uzivatele where login = '$login' and heslo = '$SHA1heslo'" pouzij "select `id` from uzivatele where login = '$login' and heslo = '$SHA1heslo' LIMIT 1" A proc $_SESSION['login'] = stripslashes($login); ? nechtels spis kdyz uz, tak htmlspecialchars pro vypis prezdivky? |
||
SeparateSK Profil |
#4 · Zasláno: 6. 1. 2012, 09:01:40
Viem nevýhoda base64 je,že sa da odsifrovat ,ale pouzijeme ho preto,aby sme session informácie zasifrovali.keby sme pouzili namiesto toho md5 alebo sha1 tak to id už asi nerozsifrujeme
|
||
Majkl578 Profil |
#5 · Zasláno: 6. 1. 2012, 09:21:07
Kubas:
„ sha1($login.$heslo) “
Seš si vědom toho, že nikdy nesmíš změnit uživatelské jméno? „ if($_SESSION['login']){ “
E_NOTICE při neexistujícím klíči. SeparateSK: „ base64_encode(stripslashes($login)) “
Chudáci ti s uvozovkou ve jménu. „Viem nevýhoda base64 je,že sa da odsifrovat ,ale pouzijeme ho preto,aby sme session informácie zasifrovali.“ Neplácej tu nesmysly. Base64 není šifrování a jeho použití tady nedává smysl. |
||
SeparateSK Profil |
#6 · Zasláno: 6. 1. 2012, 09:36:59
ano a snad tu budeme robit toto:
$_SESSION[id]=md5($row[id]); function odsifrujId($id){ $i=0; while($zI!=$id){ $zI=md5($i); $i+=1; } return $i; } $id=odsifrujId($_SESSION[id]); //fakt skvely napad :) a to este neodsifruvávame text |
||
BuGeR Profil |
#7 · Zasláno: 6. 1. 2012, 09:50:56
SeparateSK:
To je fakt "super" řešení. Pokud bude mít uživatel id např. 10 000, tak se ten cyklus provede 10 000x, aby to ID našel? |
||
SeparateSK Profil |
#8 · Zasláno: 6. 1. 2012, 10:35:08
BuGeR
ved na toto som tymto chcel narazit , ze lepsie je pouzit base64 |
||
Tori Profil |
#9 · Zasláno: 6. 1. 2012, 10:40:38 · Upravil/a: Tori
BuGeR:
„Pokud bude mít uživatel id např. 10 000, tak se ten cyklus provede 10 000x, aby to ID našel?“ SeparateSK: Proč vlastně chcete šifrovat data v session - pro případ špatného zabezpečení filesystému, kdy by se jiný uživatel dostal k souborům, kam se sessions ukládají? To už bych snad radši použila vlastní session handler (session_set_save_handler), než u každého přístupu k datům relace volat nějakou funkci. |
||
Ugo Profil |
#10 · Zasláno: 6. 1. 2012, 10:41:53
Já bych se nesnažil o změnu dat v session, ale o lepší zabezpečení samotné session. base64 je navíc zcela zcestné, když šifrovat, tak vlastní funkcí, kažopádně když ohlídáš kdo smí k session s id xxxxx, tak víc potřebovat nebudeš.
|
||
SeparateSK Profil |
#11 · Zasláno: 6. 1. 2012, 10:59:19 · Upravil/a: SeparateSK
tak aby si mal nejaku vlastnu sifru alebo nieco take , mozes pouzit napr:
$_SESSION['login'] = strrev(stripslashes($login)); //prevratime znaky v logine, takze ahoj=joha $_SESSION['id'] = dechex(($row["id"]*10)); //id nasobime 10 a prevedieme do Hexadecimalnej sustavy - takze ak je id 2,tak nove bude 2x1O -> dechex = 14, ak id=1, tak nove je "A" $login = strrev($_SESSION['login']); //prevratime naspäť, takze joha=ahoj $id = (hexdec($_SESSION['id'])/10); //opacna cesta, zistime povodne id v decimalnej sustave a delime 10 |
||
BuGeR Profil |
#12 · Zasláno: 6. 1. 2012, 14:27:24
Tori:
Já si právě říkal :-P |
||
Alphard Profil |
#13 · Zasláno: 6. 1. 2012, 15:42:17
SeparateSK:
Co to vymýšlíte za blbosti? Tyto údaje není nutné šifrovat, obvykle není problém zjistit si jméno uživatele a k ničemu to útočníkovi není. Heslo se do sessions samozřejmě ukládat nebude. Při session hijacking se krade cookies, takže šifrování sessions dat je naprosto k ničemu. Částečně může pomoci kontrola prohlížeče ([#3] blaaablaaa), ale když někdo ukradne cookies, asi si zjistí i prohlížeč. |
||
johnl Profil |
#14 · Zasláno: 6. 1. 2012, 18:30:18
Alphard:
Poté by bylo vhodné i omezení na IP adresu, nebo ne? |
||
Majkl578 Profil |
#15 · Zasláno: 6. 1. 2012, 18:35:39
johnl:
„omezení na IP adresu, nebo ne?“ Ne, je opravdu otravné, když za den jsi na třech různých místech (jiná IP) a z každého by ses musel znovu přihlašovat. |
||
johnl Profil |
#16 · Zasláno: 6. 1. 2012, 18:39:47
Majkl578:
Já bych řekl že když se budu přihlašovat ze tří různých počítačů, tak si session např. na flash disku přenášet nebudu (nebo to někdo dělá?) - snad jen u portable verze nějakého prohlížeče, spíš bych viděl problém na PC kde je dynamická IP adresa. |
||
Majkl578 Profil |
#17 · Zasláno: 6. 1. 2012, 19:09:59
Já ale nemluvil o různých počítačích. Myslím, že pro člověka, který vlastní notebook, to není až tak vyjímečná situace.
|
||
johnl Profil |
#18 · Zasláno: 6. 1. 2012, 19:43:53
Majkl578:
To je pravda, na to jsem nemyslel. :) |
||
Kubas Profil * |
#19 · Zasláno: 6. 1. 2012, 22:37:21
Děkuji za reakce - mám k tomu ještě pár dotazů -
U tohoto session se neukládá obsah do cookies. Čeká se pouze na vypršení doby session (cca 20 minut nekativity) - je to dobře, nebo je i toto nějakým způsobem chyba? Když jako session používám ID a login - nevznikají mi tím pádem pro daného uživatele vždycky stejné řetězce? Jak by se toto dalo ošetřit? Bylo by třeba vhodné řešení použít ještě $_SESSION['cas'] = date('d.n.Y H:i:s'); pro lepší zabezpečení?
Mělo by tu kdyžtak nějaký smysl použití třeba session_regenerate_id ?
Jaký význam má teda šifrování těch session pomocí base64? Omezení na IP adresy (přes htaccess?) možná není nějaký špatný nápad, nicméně co sem o tom četl, tak se to spíš nedoporučuje jako bezpečná metoda (proxy atd..) a navíc je to celkem dost otravné a asi ani moc dobře nepoužitelné.. blaaablaaa: „Jinak proti session hijackingu pouzij napr jeste kontrolu prohlizece apod.“ Co se myslí tou kontrolou prohlížeče? Ugo: „ale o lepší zabezpečení samotné session“ Co bylo myšleno tímto? Ugo: „kažopádně když ohlídáš kdo smí k session s id xxxxx, tak víc potřebovat nebudeš.“ Jak? |
||
Medvídek Profil |
#20 · Zasláno: 6. 1. 2012, 22:49:42 · Upravil/a: Medvídek
Kubas:
„U tohoto session se neukládá obsah do cookies.“ Můžete si je ukládat třeba do mysql, ale PHPSSID je většinou v COOKIES. „Jaký význam má teda šifrování těch session pomocí base64?“ Žádný „Omezení na IP adresy (přes htaccess?)“ Ne, dělá se to tak, že při začátku sezení si uložíš informace o uživateli (browser a IP adresu), která se ti během toho sezení nesmí změnit, pokud jo, tak odhlásíš. Výborně to mělo kdysi řešeno Líbimseti, které si předávalo PHPSSID v url a kamarád mi poslal odkaz s tím jeho PHPSSID a já byl hned přihlášen na něj :D |
||
Majkl578 Profil |
#21 · Zasláno: 6. 1. 2012, 23:19:40
Medvídek:
„Ne, dělá se to tak, že při začátku sezení si uložíš informace o uživateli (browser a IP adresu), která se ti během toho sezení nesmí změnit, pokud jo, tak odhlásíš.“ Tohle je přesně to špatné řešení, za které tě budou nenávidět lidé s dynamickou IP, denními aktualizacemi prohlížeče nebo měnící často IP. |
||
Medvídek Profil |
#22 · Zasláno: 6. 1. 2012, 23:55:43
Majkl578:
Při změně verze prohlížeče se snad prohlížeč stejně restartuje, takže přijdeš o sezení. A abych pravdu řekl, tak se mi během posledních 2 let na našem firemní portále nestalo, že by si zákazník stěžoval, že ho aplikace odhlásila kvůli tomu, že najednou z čista jasna dostal jinou IP adresu. (Bavíme se tu samozřejmě o ochranu během jednoho sezení. Tj. od přihlášení po odhlášení (trvalé přihlášení z bezpečnostních důvodů nepodporuju) |
||
Aleš Janda Profil |
#23 · Zasláno: 7. 1. 2012, 11:16:05
Měl bych komentář k tomuto:
Kubas: $login = mysql_real_escape_string($_POST["nick"]); $heslo = mysql_real_escape_string($_POST["heslo"]); $SHA1heslo = sha1($login.$heslo); $dotaz = mysql_query("select * from uzivatele where login = '$login' and heslo = '$SHA1heslo'"); … $_SESSION['login'] = stripslashes($login); Proč login napřed zaescapováváš a pak zase odescapováváš? Je dost matoucí, ne-li přímo chyba používat funkci mysql_real_escape_string jinde než přímo v kontextu toho dotazu. Dej ty escapovací funkce přímo do dotazu (to platí univerzálně) a nebudeš se už nikdy muset drbat s tím, jestli něco už je nebo ještě není ošetřený. A taky už NIKDY nebudeš muset použít funkci stripslashes(). Dále, zbytečně vybíráš všechny řádky (může jich vůbec být než jeden?) a všechny sloupce dotazu. Přepsal bych to takto: $dotaz = mysql_query("select 1 from uzivatele where login = '".mysql_real_escape_string($_POST["nick"])."' and heslo = '".mysql_real_escape_string(sha1($_POST["nick"].$_POST["heslo"]))."' LIMIT 1"); (Pozn.: u sha1heslo počítáš se zaescapovaným jménem a heslem (proč?). Výše uvedený můj řádek počítá s původním tvarem. Není problém kdyžtak upravit ;-)) |
||
Kubas Profil * |
#24 · Zasláno: 7. 1. 2012, 11:37:47 · Upravil/a: Kubas
Medvídek:
„Při změně verze prohlížeče se snad prohlížeč stejně restartuje, takže přijdeš o sezení.“ Ne, v tomto řešení je to řešeno tak, že je člověk přihlášený od přihlášení se do zavření stránky prohlížeče.. To byl účel nevytvářet nějaké dlouhodobé cookies.. Kubas: > Když jako session používám ID a login - nevznikají mi tím pádem pro daného uživatele vždycky stejné řetězce? Jak by se toto dalo ošetřit? > Bylo by třeba vhodné řešení použít ještě $_SESSION['cas'] = date('d.n.Y H:i:s'); pro lepší zabezpečení? > Mělo by tu kdyžtak nějaký smysl použití třeba session_regenerate_id? ? Aleš Janda: „u sha1heslo počítáš se zaescapovaným jménem a heslem (proč?)“ Heslo je ještě totiž osoleno (není zde uvedeno), tak přidání jména má za cíl zvýšit bezpečnost hesla |
||
panther Profil |
#25 · Zasláno: 7. 1. 2012, 13:28:04
Aleš Janda:
pokud je heslo hashováno, je zbytečné u něj přidávat mysql_real_escape_string . Hash je jako řetězec sám o sobě bezpečný.
|
||
Nox Profil |
#26 · Zasláno: 7. 1. 2012, 15:42:52
panther:
Radši bych to tam nechal.... pokud tam nebude takto zadrátováno "sha1" ale třeba "getPasswordHash", už není jisté, jestli z toho vždy vyjde řetězec, který nebude mít v SQL nějaký význam |
||
Kubas Profil * |
#27 · Zasláno: 8. 1. 2012, 09:59:02
Chtěl bych poděkovat všem za reakce.
Těma řešeníma sem zjistil jak by měl teda vypadat ten MYSQL zápis, zacož Alešovi dík Mám však ještě poslední dotaz na který mi zatím ještě nebylo odpovězeno, jelikož to ukradení session mě děsí nejvíc. Nevím jestli řešení od SeparateSK je nějak použitelné, jelikož když si někdo zjistí jméno a id, tak by si měl být schopný vygenerovat vlastní session ne? Proto sem dával ty svoje tři dotazy - Když jako session používám ID a login - nevznikají mi tím pádem pro daného uživatele vždycky stejné řetězce? Jak by se toto dalo ošetřit? Bylo by třeba vhodné řešení použít ještě $_SESSION['cas'] = date('d.n.Y H:i:s'); pro lepší zabezpečení? Mělo by tu kdyžtak nějaký smysl použití třeba session_regenerate_id? Díky za reakce |
||
Nox Profil |
#28 · Zasláno: 8. 1. 2012, 10:04:55
1) Identifikátor Session se neřídí podle obsahu, to si asi teď pleteš s hashováním ... Session ID se náhodně generuje na serveru
2) Viz (1) 3) Session_regenerate_id() se doporučuje http://en.wikipedia.org/wiki/Session_fixation http://en.wikipedia.org/wiki/Session_hijacking |
||
Alphard Profil |
#29 · Zasláno: 8. 1. 2012, 10:28:49
[#27] Kubas
Máte v tom pořád, zdá se mi, dost zmatek. Zkuste si pročíst http://php.vrana.cz/zabezpeceni-session-promennych.php. Jakékoliv šifrování dat nebo přidávání času je k ničemu. |
||
Časová prodleva: 12 let
|
0