Autor Zpráva
Keilew
Profil
Ahoj, potřeboval bych pomoct od znalce PHP. Nejsem v PHP moc zběhlý a tak nevím, na co si dávat pozor, když vytvářím systém přihlašování do nějaké privátní oblasti. Co jsem načet na webu, to jsem tam zakomponoval, teď je jen otázka, zda je to všechno. Nenašel by se někdo, kdo by se zkusil podívat na http://test.optimic.cz/ a prolomit se dovnitř? Pokud se to povede (doufám, že ne), tak ty errory, co tam jsou, jsou kvůli tomu, že jsem musel vymazat celý obsah, tak se nelekněte:-)
Je mi jasné, že když nepoužívám SSL, dá se odposlechnout heslo apod. Teď mi ale jde o odstínění hrubých chyb a slabých míst, která by byl schopen prorazit i "obyčejný" PHPkář.
Předem dík!
Joker
Profil
Vypadá to, že proti základním "fíglům" to odolné je. Ale lepší by bylo dát sem popis toho jak je to udělané.
Ale tipuju, že amatérský rádobyhacker by se tam nedostal :-)
Keilew
Profil
Udělaný je to jednoduše. Skriptu se předhodí login a heslo a ten zkontroluje jejich hash s uloženou heashí na serveru. Předtím se samozřejmě vyhází nebezpečné znaky.
ronnie
Profil
Ideální by bylo překopírovat skript přímo do diskuse a pak hledat chyby tam. Jinak důrazně doporučuji odstranit buttonek "vymazat".
Keilew
Profil
ronnie

OK, já ho trošku upravím (je ve více souborech) a večer ho sem hodím. Jinak bych prosil vysvětlit, proč odstranit ten buttonek;-)
ronnie
Profil
Proože je to na nic. Kdy jsi to realně využil?
Keilew
Profil
Skript té stránky, co vidíte:


include_once("logic/functions/login.php");

if (isset($_POST["send"])) $send = safety($_POST["send"]); else $send = null;
if (isset($_POST["nick"])) $nick = safety($_POST["nick"]); else $nick = null;
if (isset($_POST["pwd"])) $pwd = safety($_POST["pwd"]); else $pwd = null;

if (($send != null) && ($nick != null) && ($pwd != null)) {
$prio = login_validation($send, $nick, $pwd);
if ($prio >= 0) {
$hash = create_hash(...); // neni dulezite zde rozebirat...
if (strlen($hash) == 32) {
$_SESSION["hash"] = $hash;
print ("<script language="JavaScript"> window.location.replace('/base/".(SID == "" ? "" : "?".SID)."'); </script>");
print("<p class="center">Pokud nedojde k automatickému přesměrování, pokračuj <a href="/base/".(SID == "" ? "" : "?".SID)."">zde</a></p>");
} else print("<p class="error">Nepodařilo se vytvořit hash. Zkuste to prosím znovu.</p>");
} else {
if ($prio == -4) print("<p class="error">Špatné heslo nebo přihlašovací jméno!</p>"); else print("<p class="error">Nepodařilo se spojit s databází. Zkuste to prosím znovu.</p>");
}
} else {
// varianta, ze doslo k poslani, ale s nepripustnymi znaky
if ($send != null) {
print("<p class="error">Buďto jste nevyplnil některý povinný údaj nebo používáte zakázané znaky!</p>");
} else {
//nic neni vyplneno, zobraz jen formular popr. chybu (vola hash)
if (isset($_GET["eid"])) {
// je nejaky error
switch ($eid) {
case "0": $message = "Odhlášení ze systému proběhlo úspěšně."; break;
case "-2": $error = "Odhlášení ze systému neproběhlo úspěšně: database error!"; break;
case "-3": $error = "Odhlášení ze systému neproběhlo úspěšně: hash error!"; break;
case "-4": $error = "Vypršela Vám hash, musíte se znovu přihlásit!"; break;
case "-5": $error = "Neplatná stránka nebo hash! Znovu se přihlašte!"; break;
default: $error = "Jiná chyba!";
}
if (isset($error)) { session_destroyer(); print("<p class="error">$error</p>"); }
if (isset($message)) print("<p class="center">$message</p>");
}
}
}
dále je jen formulář...


V includovaných souborech


function login_validation($send, $nick, $pwd) {
if ($send != "vstoupit") return -1;
// porovnat nick a pwd s databazi
do {
$spojeni = MySQL_Connect("...","...","...");
if (!$spojeni) { return -2; break; }
MySQL_Select_DB("...");
$vysledek = MySQL_Query("SELECT pwd, prio FROM table WHERE login = '".md5($nick)."'");
if (!$vysledek) { return -3; break; }
$zaznam = MySQL_Fetch_Row($vysledek);
$true_pwd = $zaznam[0];
$prio = $zaznam[1];
MySQL_Close($spojeni);
} while (false);
if ((md5($pwd) == $true_pwd)) return $prio; else return -4;
}




function safety($str) {
return eregi_replace('[^0-9a-z-\_]', '', $str);
}


Asi to není žádná nádhera...:-)
Keilew
Profil
ronnie

Asi nikdy, ale na škodu to taky není, nebo ne?
ronnie
Profil
Je to na škodu. Co když někdo vyplní formulář a omylem klikne na "Vymazat"?
Kcko
Profil
do {

}


while (false);

k cemu to slouzi? Neni to trosku zastarala konstrukce?
Keilew
Profil
Kcko

Kosek - učebnice PHP:-) Je to tam nanic, já vím...
loyza
Profil
Myslím si, že když používáš hash loginu a hash hesla tak si ušetříš spoustu starostí a navíc spoustu útoků odstraníš. To je dobrá věc, myslím si, že lépe to snad ani nejde a že to bude dost bezpečné. Ale já nejsem žádný velký odborník na bezpečnost, tak počkám jestli se k tomu vyjádří někdo jiný.
Asi bych raději používal funkci sha1 místo md5. Je bezpečnější, ale v tomhle případě to zas tak velký problém není.
BTW. máš nějaký důvod proč ten login a to heslo nehashovat hned na začátku skriptu a dále pracovat pouze s hashem?? Také by potom klidně mohly být povoleny všechny znaky v loginu i hesle. Myslím.
Keilew
Profil
máš nějaký důvod proč ten login a to heslo nehashovat hned na začátku skriptu a dále pracovat pouze s hashem??

Výborná poznámka, díky. Upravím to.
Keilew
Profil
Ještě nějaké nápady, zlepšováky?
buck
Profil *
jo napadá mě že by si mohl změnit proměnné

if (isset($_POST["send"])) $send = safety($_POST["send"]); else $send = null;
if (isset($_POST["nick"])) $nick = safety($_POST["nick"]); else $nick = null;
if (isset($_POST["pwd"])) $pwd = safety($_POST["pwd"]); else $pwd = null;


$send $nick $pwd

na jiný než než které dostáváš z formuláře...takhle nikdo neuhodne které proměnné používáš.

příklad:

if (isset($_POST["send"])) $sended_form = safety($_POST["send"]); else $sended_form = null;

a pak samozřejmě to změnit dále ve scriptu

předem říkám že nejsem hacker, a že to může být blbost
Toto téma je uzamčeno. Odpověď nelze zaslat.