Autor | Zpráva | ||
---|---|---|---|
gardener Profil |
#1 · Zasláno: 4. 6. 2009, 00:03:48
Zdravím,
Napsal jsem si skript pro přihlašování uživatelů, který by se dal rychle nasadit na website v případě potřeby, nejsem si ale moc jistý jak je to s efektivností kódu a jeho bezpečností. Takže pokud by někdo tušil jak to napsat lépe, nebo čeho se vyvarovat budu jedině rád za připomínky. Jak pracuje? Dta z formu vezmeme, ověříme, zda byla vubec zadána, pokud ne, informujeme, pokud ano, zavoláme fci pro ověření se dvěma vstupními parametry. fce si "šáhne do tabulky" uživatele apokud najde víc ja 0 řádků shody nastaví potřebné hodnoty pro session a končí, na základě nastavených hodnot, rozlišíme zda je to uživatel, admin, nebo omyl a přesměrováváme. Díky za každou radu. Form <!-- CONNECT TO THE DB --> <?php include_once("db_pripoj.php"); include_once("db_vytvor.php"); include_once("functions.php"); ?> <!-- CATCHING $GET AND INCLUDING CONTENT --> <?php $action = $_GET["action"]; if ($action == "over_usera") {include ("over_usera.php");} ?> <form action="index.php?action=over_usera" id="" class="center" name="form" method="post" enctype="multipart/form-data"> <fieldset> <legend>Přihlášení uživatele</legend> <label for="prijmeni">Login:</label> <br /> <input type="text" id="log" name="log" /> <br /> <label for="heslo">Password:</label> <br /> <input type="password" id="heslo" name="password" /> <br /> <br /> <?php //Only if form is submitted //Pass throught array if (isset($action)) { $arr = $hlaska_vlozeni; foreach ($arr as $value) { echo("$value<br/>"); } } unset($value); // break the reference with the last element ?> <input name="submitt" type="submit" value="Přihlásit" /> Overeni <?php session_start(); ?> <?php $prihlasen_admin= "admin.php"; $prihlasen_uzivatel= "uzivatel.php"; $neprihlasen= "index.php"; error_reporting(E_ALL); //Reporting about all errors $log = (mysql_real_escape_string($_POST["log"])); $password = (mysql_real_escape_string($_POST["password"])); if (empty($log) | empty($password)) { $hlaska_vlozeni[] = "Nevyplnili jste potřebné údaje"; } else { //Call function for verifu, that user is admin,normal user or not overeni($log, $password); if(($_SESSION['prihlasen'] == 1) & ($_SESSION['is_admin'] == 1)) { echo "<script>location.href=\"$prihlasen_admin\";</script>"; } else if(($_SESSION['prihlasen'] == 1) & ($_SESSION['is_admin'] == 0)) { echo "<script>location.href=\"$prihlasen_uzivatel\";</script>"; } else { $hlaska_vlozeni[] = "špatně zadané údaje"; } } ?> Fce kterou voláme <?php //FUNKCE PRO OVERENI ZDA JE UZIVATEL ADMIN, CI NENI, PODLE TOHO ZDA MA V TABULCE UVEDENO 0 CI 1 //POKUD SE VSE OSTATNI SHODUJE, T. PRIJMENI A MAIL, TAK PRESMERUJEME BUD NA ADMIN.PHP NEBO NA VYPIS.PHP function overeni($log, $password) { $_SESSION['prihlasen'] = 0; $_SESSION['is_admin'] = 0; $q = mysql_query("SELECT je_admin FROM uzivatele WHERE log='$log' AND heslo='$password'"); if (mysql_num_rows($q) > 0) { list($jeadmin) = mysql_fetch_row($q); if ($jeadmin) { $_SESSION['prihlasen'] = 1; $_SESSION['is_admin'] = 1; } else { $_SESSION['prihlasen'] = 1; $_SESSION['is_admin'] = 0; } } else { $_SESSION['prihlasen'] = 0; $_SESSION['is_admin'] = 0; return false; } } ?> |
||
tiso Profil |
#2 · Zasláno: 4. 6. 2009, 00:23:13
gardener - začni tým, že nebudeš ukladať heslo do databázy v plain forme, ale iba jeho hash (md5, sha1, ...)
|
||
TomášK Profil |
#3 · Zasláno: 4. 6. 2009, 01:15:50 · Upravil/a: TomášK
tiso
Ještě se do dá vylepšit o salt (neznám adekvátní překlad) a do databáze ukládat md5(salt+password) - kvůli rainbow tables. Ke kódu: * rozhodni se, jestli chceš psát česky nebo anglicky, kombinace vypadá dost příšerně (over_usera apod.) * dodržuj odsazení, máš dvakrát za sebou na začátku řádku } (pokud se to nerozhodilo až při kopírování) * odstaň výstup před session_start() * zjisti, jaký je rozdíl mezi | a || * error_reporting(E_ALL) považuju za rozumné při vývoji, na produkčním serveru to nemá co dělat - uživatel by se měl dozvědět, že nastala jaká chyba, ale chybový výpis by se mu zobrazit neměl * kód by na mnoho místech šel upravit, aby byl čitelnější. |
||
gardener Profil |
#4 · Zasláno: 4. 6. 2009, 01:58:29
Díky, určitě se na to zaměřím
S tím MD5..tam jde ale o jednostranné šifrování ne? Takže pokud bych potřeboval zjistit, pouze z db heslo, tak jak jej zadal uzivatel, tak bych asi nepochodil že? |
||
TomášK Profil |
#5 · Zasláno: 4. 6. 2009, 03:39:01
S tím MD5..tam jde ale o jednostranné šifrování ne? Takže pokud bych potřeboval zjistit, pouze z db heslo, tak jak jej zadal uzivatel, tak bych asi nepochodil že?
Ano, md5 je jednostrané šifrování, ale ono to nevádí - dokonce víc, je to žádoucí. Ty nepotřebuješ vědět, jaké má uživatel heslo. Víc než to, ty to nechceš vědět. Připustíme-li možnost, že někdo pronikne do databáze, pak tam najde jen md5 hashe hesel - ovšem ty mu budou na nic, protože z nich nezjistí přímo ta hesla - nedokáže se přihlásit pod libovolným uživatelem. Jediné, kdy by se mohlo hodit znát přímo heslo, je situace, kdy ho uživatel zapomněl. Pak ale nic nebrání tomu vygenerovat nové heslo. |
||
fuckin Profil * |
#6 · Zasláno: 4. 6. 2009, 06:30:56
ta funkce overeni me prijde ponekud zmatena, proc vracis false ale true nikoli? Nebude lepsi z toho udelat rovnou proceduru ? Nebo funkci ktera bude vracet true a false a pak nasledne po zjisteni true nebo false zapsat session?
- nekombinuj anglictinu a cestinu dohromady - vis jaky je rozdil mezi | a || ? - vytvor spis funkci overit ktera bude vracet true a false a funkci jeAdmin ktera bude taky boolean -neumis odratkovavat text (beru zpet jestli je to timto forem) - o sha1 ani nemluve... |
||
gardener Profil |
#7 · Zasláno: 4. 6. 2009, 08:21:23
o.k zaimplementuji tam MD5, bude to tak lepší.
Co se týče připomínek: - nekombinuj anglictinu a cestinu dohromady (Souhlas, psal jsem to v češtině abych se dobře orientoval při psaní ale vždycky jsme dostal nějaký cuk to psát angicky, takže z toho vznikl tenhle hybrid. ) - vis jaky je rozdil mezi | a || ? (No myslím, že u | je potřeba aby byly splněny obě dvě podminky a u || se jedná o neexkluzivní log. součet takže bude vracet true, pokud bude min. jedna hodnota správně) - vytvor spis funkci overit ktera bude vracet true a false a funkci jeAdmin ktera bude taky boolean (Nevím, jestli to není spíš zesložitění ty návratové hodnoty T a F jsem tam ale opravdu zbytečně) -neumis odratkovavat text (beru zpet jestli je to timto forem) (Zřejmě fórem) - o sha1 ani nemluve... |
||
Nox Profil |
#8 · Zasláno: 4. 6. 2009, 09:10:13
„(No myslím, že u | je potřeba aby byly splněny obě dvě podminky a u || se jedná o neexkluzivní log. součet takže bude vracet true, pokud bude min. jedna hodnota správně)“
Ne-e, v PHP to je často tak, že 1 operátor je akce a 2 je porovnání...čili | by měl imho být logický součet dvou členů, což ve většině případů v podmínce nechceš Stejně tak na několika místech máš místo && jen logický součin...ikdyž výsledek by měl být asi stejný Obě podmínky splněny: && Alespoň 1: || |
||
imploder Profil |
#9 · Zasláno: 4. 6. 2009, 11:04:21
Zdá se mi, že tam chybí zapamatování ID uživatele v $_SESSION, aby pak šlo zjistit, který je to uživatel.
gardener „- vis jaky je rozdil mezi | a || ? (No myslím, že u | je potřeba aby byly splněny obě dvě podminky a u || se jedná o neexkluzivní log. součet takže bude vracet true, pokud bude min. jedna hodnota správně)“ Nn, | je bitový součet. Jako logický OR bude fungovat jenom s operandy typu bool. |
||
Lamicz Profil |
#10 · Zasláno: 5. 6. 2009, 22:36:30
„Připustíme-li možnost, že někdo pronikne do databáze...“
A ja budu tvrdit, ze sifrovani hesel, pokud se dane heslo nikde nepredava (napr. v SESSION nebo se neuklada do COOKIE), je k nicemu. Kdyz se Ti nekdo dostane do databaze, muze si udelat stejne co chce, svym libovolnym uctem pocinaje a smazanim cele databaze konce. Proc by proboha zjistoval nekomu ucet a lamal md5??. Sifrovani hesel je dobry jenom na jedinou vec - pres SQL injekci nebo XSS se nekam vypise tabulka s ucty. Tot vse. |
||
pEeLL Profil |
#11 · Zasláno: 5. 6. 2009, 22:44:21
Lamicz
Kdyz se Ti nekdo dostane do databaze, muze si udelat stejne co chce, svym libovolnym uctem pocinaje a smazanim cele databaze konce. Proc by proboha zjistoval nekomu ucet a lamal md5??. a ted si vem ze tento uzivatel by mel stejne jmeno treba pro svuj mail, kde by mel ulozene maily z ruznych jinych registraci ve kterych by byla ruzna hesla nebo jine citlive informace. pokud v databazi najde jen hash tak maximalne ovladne dany ucet/web. |
||
Lamicz Profil |
#12 · Zasláno: 5. 6. 2009, 22:53:59
pEeLL
Tohle je ale nejvic blbost daneho uzivatele, a navic pokud je to heslo jednoduchy (coz ono vetsinou je), tak je ten hash stejne naprd. Do te databaze se proste nikdo cizi dostat nesmi. Tecka. BTW proto se na hodne mistech hesla generuji a nejdou menit. |
||
Visitor Profil * |
#13 · Zasláno: 6. 6. 2009, 08:12:15
Nejde to ze zapisu poznat a nebylo zmineno...
- indexy nad databazi -- unikatni nad "log" -- a aby slo rychle vyhledavat, tak index nad "log" + "heslo" |
||
imploder Profil |
#14 · Zasláno: 6. 6. 2009, 13:36:23
Lamicz
„Tohle je ale nejvic blbost daneho uzivatele, a navic pokud je to heslo jednoduchy (coz ono vetsinou je), tak je ten hash stejne naprd.“ Na to se právě heslo před zahashováním solí, pak to tak jednoduché není. „Do te databaze se proste nikdo cizi dostat nesmi. Tecka. “ Může nastat případ, kdy si např. pomocí sql-injection někdo zpřístupní údaje z databáze, ale jenom pro četení (tj. něco se mu vypíše). Pokud je nedostatečně zabezpečený jenom nějaký skript tahající data z databáze a ne zapisující a SQL-injectionem jde jenom nějaká data vytáhnout, tak má smysl mít hesla nečitelná. Útočník si tak akorát přečte něco z databáze, ale žádný uživatelský účet neovládne. |
||
Časová prodleva: 16 let
|
0