neivoll Skrevet 9. mars 2006 Del Skrevet 9. mars 2006 Tenkte vel på $_SERVER['HTTP_USER_AGENT'] ja. Lenke til kommentar
MC2 Skrevet 9. mars 2006 Forfatter Del Skrevet 9. mars 2006 ja... stemmer det fiksa nå. Lenke til kommentar
Ernie Skrevet 9. mars 2006 Del Skrevet 9. mars 2006 Ok. Men det bør iallfall opp på sjekklisten da, å pakke inn i addslashes() eller lignende. Hva er forresten forskjellen på addslashes() og mysql_real_escape() ? Gjør de akkurat det samme? 5725184[/snapback] Ja, for de fleste her vil de gjøre eksakt det samme. En kverulant vil raskt rette meg og si at mysql_real_escape også tar et par tegn til, men disse har ingen praktisk betydning og escapes bare for at loggen ikke skal fuckes helt opp. mysql_real_escape vil være å foretrekke hvis man benytter mysql-database. edit: [*]Ikke bare sjekke brukernavn og passord. Skriv innlogginstida og ip, og sjekke om ipen stemmer (dette er for å hindre session hijacking, leste om det i en artikkel) og om tida er innenfor en bestemt timeout. (mulig dette er fiksbart med session_cache_expire, er ikke sikker) 5724029[/snapback] Så at Ernie (tror jeg det var) skrev en annen plass at det også var lurt å sjekke ting som browser osv. Vet ikke hvor mye sikkerhet det gir med sånne småting akkurat, men kan kanskje være verdt å ta med. 5725184[/snapback] Ja, det kan være lurt å notere seg ned nettleser samt også kjøre den igjennom en hash-funksjon (dvs. md5 eller sha1). Grunnen til dette er for å hindre at noen kan kapre session hvis man benytter en proxy-server eller delt IP. Lenke til kommentar
genstian Skrevet 9. mars 2006 Del Skrevet 9. mars 2006 (endret) Mitt login script <?php function Login() { global $screen, $SYS, $DB, $LOGIN, $lang, $COOKIE, $Login, $user; // Do we allready is Logged in? if($user->Login == 1) { // Header to index header("Location:index.php"); } if(!isset($_POST['submit'])) { $HTML['L_Username'] = $lang['Username']; $HTML['L_Password'] = $lang['Password']; $HTML['L_Remember'] = $lang['Remember']; $HTML['L_Hide'] = $lang['Hide']; $screen->Add_HTML('Login', $HTML); } else { $Username = $_POST['username']; $Password = $_POST['password']; $Remember = 0; if(isset($_POST['remember'])) $Remember = 1; $Hide = 0; if(isset($_POST['hide'])) $Hide = 1; // Include hash driver require ($SYS['Path'] . '/Includes/HASH/' . $LOGIN['Hash_Driver'] . '.php'); // Get user id (if user exist) $Id = $DB->Get_User_Id($Username); if(!$Id) { $Msg = $lang['Login_Fail_User_Pass']; } else { // Check if a user is logged in with this IP $IP = $_SERVER['REMOTE_ADDR']; if($DB->Check_IP_Login($IP)) { // Do a logout $timeout = time()- 31536000; setcookie('wep_session_id', '', $timeout, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_uid', '', $timeout, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_theme', '', $timeout, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_language', '', $timeout, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_visit', '', $timeout, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); // Unset Session $DB->Remove_Session(null, $IP); } // Get salt and password $Data = $DB->Get_User_Login($Id); $Salt = $Data->salt; $DB_Password = $Data->password; // Calculate Password and check if it match $Password = Hash($Password, $Salt); if($Password == $DB_Password) { $time = time(); $DB->Update_Last_Login($time, $Id); $DB->Set_Session(md5($IP . $time), $Id, $IP, $time, $Remember, $Hide); if($Remember != "") { setcookie('wep_session_id', md5($IP . $time), $time+31536000, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_uid', $Id, $time+31536000, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); } else { setcookie('wep_session_id', md5($IP . $time), null, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_uid', $Id, null, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); } header("Location:index.php"); } } // If not user is send to index page by now, print error page. $screen->Add_HTML('Error', array('MSG' => $Msg)); } } function Logout() { global $DB, $user; // Must be logged in to log out. if($user->Login == 1) { $time = time()- 31536000; setcookie('wep_session_id', '', $time, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_uid', '', $time, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_theme', '', $time, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_language', '', $time, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); setcookie('wep_visit', '', $time, $COOKIE['Path'], $COOKIE['Domain'], $COOKIE['Secure']); // Unset session $DB->Remove_Session($user->Session); } header("Location:index.php"); } Database fungsjonene: function Get_User_Login($id) { $this->Query("SELECT password, salt FROM {$this->Prefix}users WHERE id = '$id' LIMIT 1"); return $this->row(); } function Update_Last_Login($Time, $id) { $this->Query("UPDATE {$this->Prefix}users SET `last_login` = '$Time' WHERE id = '$id' LIMIT 1"); } function Set_Session($SID, $UID, $IP, $Time, $Remember, $Hide) { $this->Query("INSERT INTO {$this->Prefix}session ( `sid` , `uid` , `time` , `ip` , `stayin` , `hide` ) VALUES ( '$SID', '$UID', '$Time', '$IP', '$Remember', '$Hide' )"); } function Check_Session($SID, $UID) { $IP = $_SERVER['REMOTE_ADDR']; $this->Query("SELECT * FROM {$this->Prefix}session WHERE sid='$SID' AND ip='$IP' AND uid='$UID' LIMIT 1"); return $this->row(); } function Remove_Session($SID, $IP = 0) { if($IP == 0) { $this->Query("DELETE FROM {$this->Prefix}session WHERE `sid` = '$SID'"); } else { $this->Query("DELETE FROM {$this->Prefix}session WHERE `ip` = '$IP'"); } } function Check_IP_Login($IP) { $this->Query("SELECT ip FROM {$this->Prefix}session WHERE `ip` = '$IP'"); $Match = $this->row(); $Match = $Match->ip; if($Match == $IP) { return true; } return false; } Gjort før med $_GET, $_POST og $_COOKIE: foreach($_GET as $row => $value) { if(!get_magic_quotes_gpc()) { $value = addslashes($value); } $row = trim($row); $value = trim($value); $_GET[$row]= $value; } foreach($_POST as $row => $value) { if(!get_magic_quotes_gpc()) { $value = addslashes($value); } $row = trim($row); $value = trim($value); $_POST[$row]= $value; } foreach($_COOKIE as $row => $value) { if(!get_magic_quotes_gpc()) { $value = addslashes($value); } $row = trim($row); $value = trim($value); $_COOKIE[$row]= $value; } Endret 9. mars 2006 av hotstian Lenke til kommentar
MC2 Skrevet 10. mars 2006 Forfatter Del Skrevet 10. mars 2006 Tror jeg fant ut en måte å motstå "man-in-the-middle" attacks, uten å ty til https. Mulig det går å legge inn et javascript md5 hasher som krypterer passordet mens brukeren skriver for så og sende den krypterte strengen til servern. fant flere sånne scripts på google: http://pajhome.org.uk/crypt/md5/md5src.html men problemet kommer da til de som har javascript deaktivert... er dette lurt eller poengløst? Lenke til kommentar
Ernie Skrevet 10. mars 2006 Del Skrevet 10. mars 2006 (endret) Tror jeg fant ut en måte å motstå "man-in-the-middle" attacks, uten å ty til https. Mulig det går å legge inn et javascript md5 hasher som krypterer passordet mens brukeren skriver for så og sende den krypterte strengen til servern. fant flere sånne scripts på google: http://pajhome.org.uk/crypt/md5/md5src.html men problemet kommer da til de som har javascript deaktivert... er dette lurt eller poengløst? 5730496[/snapback] Vil tro det er rimelig poengløst. Har man reel grunn til å tro at noen gidder å lytte på trafikken så bruker man https. Vil man vite om js er aktivert så sender du jo bare med en ekstra variabel som f.eks js_aktiv og setter i utgangspunktet lik false, men til true gjennom js. Dog åpner man et nytt hull med det her. Sett et bruker kjenner hash-en, men ikke hva passordet egentlig er? Endret 10. mars 2006 av Ernie Lenke til kommentar
MC2 Skrevet 23. august 2006 Forfatter Del Skrevet 23. august 2006 (endret) For å videre sikre passord er det lurt å bruke salting. Dette vil praktisk talt ødelegge dictionary lookup metdoen, rainbow tables og sakte ned en bruteforcer. Det som gjøres er at hvis en person har "hei" som passord vil det ikke ta lenge for en angriper (som har hashen) å finne passordet via en rainbow table eller dictionary lookup. Mens bruteforcing på en normal pc kanskje bare tar en dag eller noe. Altså, for å hindre at dette skjer lagrer man saltet (som er en tilfeldig streng) i tillegg til brukernavn og passord-hash i databasen. Så hvis en bruker har "hei" som passord legger man til saltet foran sånn at det blir "S#GH'l5!iy3p'cJ15$~F!6XxR3z$O2n0hei" og hasher denne strengen istedet. Det finnes nok ingen rainbowtables som har hashet en sånn streng. Og hvis angriperen har saltet ville det ikke hjelpe heller. For å kunne bruke dictionary lookup metoden må han re-hashe hele ordboka med saltet foran (eller bak som også er en mulighet). I tillegg vil bruteforcing fort bli utrolig tidkrevende. Problems solved. <?php /* SALTER Designed for "salting hashes". Returns a 32 character long random string including a-z,A-Z,0-9 and some special characters. Function can be used to generate random passwords. */ function make_salt() { // a secure password needs a-z,A-Z,0-9 and some special characters // (actually, it doesn't really matter since the hash will be very // different no matter... But, it makes it harder to bruteforce.) $az = array("a","b","c","d","e","f","g","h","i","j","k","l","m", "n","o","p","q","r","s","t","u","v","w","x","y","z"); $AZ = array("A","B","C","D","E","F","G","H","I","J","K","L","M", "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); $chars = array(".",",","/","&",":",";","-","_","*","(",")","[","]", "{","}","+","?","%","#","!","<",">","~","$",'"',"'", "@",";","="); // lets have 8 random numbers for($i=0; $i<8; $i++) { $str[] = rand(0,9); }; // lets have 8 random a-z for($i=0; $i<8; $i++) { $str[] = $az[rand(0,count($az)-1)]; }; // lets have 8 random A-Z for($i=0; $i<8; $i++) { $str[] = $AZ[rand(0,count($AZ)-1)]; }; // lets have 8 random special characters for($i=0; $i<8; $i++) { $str[] = $chars[rand(0,count($chars)-1)]; }; // lets shuffle it //$str = preg_split('//',$str,-1,PREG_SPLIT_DELIM_CAPTURE); shuffle($str); $str = implode("",$str); return $str; }; header("Content-type: text/plain; charset=UTF-8"); var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; var_dump(make_salt()); echo "\n"; ?> aiiii, la til for loops istedet. Endret 23. august 2006 av MC2 Lenke til kommentar
Peter Skrevet 23. august 2006 Del Skrevet 23. august 2006 Litt looper inni der ville gjort seg, vet du. Kortere kode, mer oversiktlig, og mye enklere å skrive... (snakker da spesielt om "lets have..."-delene) Lenke til kommentar
genstian Skrevet 23. august 2006 Del Skrevet 23. august 2006 (endret) Login2: function createSession($uid) { global $DB; // First create a SID $time = time(); $IP = $_SERVER['REMOTE_ADDR']; $SID = sha1($IP . $time . $_SERVER['HTTP_USER_AGENT']); // Then Put it into DB $DB->query('INSERT INTO '.SESSION_TABLE." ( `session_id` , `session_uid` , `session_started` , `session_ip`) VALUES ( '$SID', '$uid', '$time', '$IP')", 0); return $SID; } if(isset($_POST['submit'])) { $Username = addslashes($_POST['username']); $Password = addslashes($_POST['password']); $Remember = (empty($_POST['remember']) ? 0 : 1); $Hide = (empty($_POST['hide']) ? 0 : 1); // Make it take some time sleep(1); // Maybe like 5sec for extra securitty // Get user data (if user exist) $DB->query('SELECT id, password, active, salt FROM '.USER_TABLE.' WHERE username = \''.$Username.'\' LIMIT 1'); $data = $DB->fetch(); $id = $data['id']; // Username or password wrong? if(!$id || $data['password'] != pwhash($Password, $data['salt'])) { $Message = $lang['Login_Fail_User_Pass']; } // User not activated? if(!$data['active']) { $Message = $lang['User_Not_Activated']; } $SID = createSession($id); if($Remember != "") { setcookie($conf['Cookie_Prefix'] . 'sid', $SID, time()+31536000, $conf['Cookie_Path'], $conf['Cookie_Domain'], $conf['Cookie_Secure']); } else { setcookie($conf['Cookie_Prefix'] . 'sid', $SID, null, $conf['Cookie_Path'], $conf['Cookie_Domain'], $conf['Cookie_Secure']); } // Redirect back to index redirect("index.php"); } //$template->add_javascript('sha2'); valgfri // If not user is send to index page by now, print error page. if(isset($Message)) $template->body('Error', array('MESSAGE' => $Message)); $template->body('Login'); ?> $template->body => Legg til html coden (du kan bruke include()) $lang => Språk arrayen (For multispråk, du kan inline) $conf => Enkel configurasjon (Se scriptet, kan inlines) $DB->Query() => Utfør database query (mysql(i)_query()) $DB->fetch() => mysql(i)_fetch_assoc() SESSION_TABLE => sesions tabelen USER_TABLE => bruker tabelen Elsker kode der folk må gjøre noe for å bruke det. Eksempel form <form action="login.php" method="POST""> USERNAME: <input type="text" name="username" /><br /> PASSWORD: <input type="password" name="password" /><br /> REMEMBER: <input type="checkbox" name="remember" /> HIDE: <input type="checkbox" name="hide" /><br /> <input type="hidden" name="submit" value="1" /> <input type="submit" /> </form> Konfig $dbprefix = 'login_'; define('USER_TABLE', $dbprefix.'users'); define('SESSION_TABLE', $dbprefix.'session'); $conf['Cookie_Domain'] = ''; $conf['Cookie_Path'] = '/wep/'; $conf['Cookie_Secure'] = 0; $conf['Cookie_Prefix'] = 'wep_'; Funsjoner function pwhash($pw, $salt) { return sha1($salt.$pw); //Custom your way } Resten fikser du selv. (Loginscript er best slik) Endret 23. august 2006 av hotstian Lenke til kommentar
genstian Skrevet 23. august 2006 Del Skrevet 23. august 2006 Enklere salt (kortere kode): $chars = array( 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', 'g', 'G', 'h', 'H', 'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ':', '.', '-', '_', '?', '+', '/', '\'', '"', '}', '{', '[', ']', '(', ')'); $max_chars = count($chars) - 1; $rand_str = ''; for($i = 0; $i < $length; $i++) { $rand_str .= $chars[mt_rand(0, $max_chars)]; } return $rand_str; Generer SID function createSession() { // create a SID $time = time(); $IP = $_SERVER['REMOTE_ADDR']; $SID = sha1($IP . $time . $_SERVER['HTTP_USER_AGENT']); return $SID; } Lenke til kommentar
Ernie Skrevet 24. august 2006 Del Skrevet 24. august 2006 Generer SID function createSession() { // create a SID $time = time(); $IP = $_SERVER['REMOTE_ADDR']; $SID = sha1($IP . $time . $_SERVER['HTTP_USER_AGENT']); return $SID; } 6732670[/snapback] Den der tviler jeg på om blir tilfeldig nok. Sett at noen sitter på jobb bak en proxy, begge bruker samme nettleser og logger seg inn på eksakt det samme tidspunktet? Da vil faktisk session være eksakt lik. Dessuten vil den i aller høyeste grad være forutsigbar. Skal du lage sessionid selv så må den være så tilfeldig som du overhode klarer å få den. $session_id = sha1(uniqid(mt_rand(), true)); Stort mer tilfeldig enn det der tror jeg ikke du får det. Lenke til kommentar
Peter Skrevet 24. august 2006 Del Skrevet 24. august 2006 Skal en del til før de treffer på akkurat samme sekundet, og evt. kan du jo bruke microtime(), men resten er faktisk ganske sannsynlig. (browser og proxy) Virker egentlig for meg som at å mikse inn browser gir litt falsk følelse av sikkerhet. Ihvertfall med tanke på at det bare er 3 browsere på markedet, hvorav 2 deler 98%, og igjen én sitter med 80-90% av det igjen. IP fungerer vel også dårligere ettersom fler og fler ender bak en ruter/gateway/proxy. Lenke til kommentar
genstian Skrevet 24. august 2006 Del Skrevet 24. august 2006 Bedre en uniqid()? function createSession() { // create a SID $time = microtime(); $IP = $_SERVER['REMOTE_ADDR']; $string_num = mt_rand(6, 22); $string = ''; for($i = 0; $i <= $string_num; $i++) $string += chr(mt_rand(0, 255)); $SID = sha1($IP . $time . $string . $_SERVER['HTTP_USER_AGENT'] . $string_num); return $SID; } Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå