Login Security !

Reply

Join Date: Sep 2005
Posts: 1,083
Reputation: digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice 
Solved Threads: 66
Moderator
digital-ether's Avatar
digital-ether digital-ether is offline Offline
Veteran Poster

Re: Login Security !

 
1
  #11
Jul 9th, 2007
Originally Posted by invisal View Post
It is not 100% match for using OCR to read the image right? Plus the image is created which randomly content. Even the attacker collect more than 1000 of images that have been appear on the login, the next image will be probally different from the previous. I guess the robots aren't so effective after all now. Correct me if i am wrong...
The login form is just there for the browser. It is only a "template" to tell the browser how to make the next HTTP Request to the server.
A bot will not need the login form, just the correct details to make the valid HTTP Request.. It only needs to get the CAPTCHA image, see if it can guess it or not. If it thinks OCR has a match, it will then make a login attempt.
So, it is still affective if it downloads many images. If the server can serve 50 000 images a second, then the bot can make 500 login attempts a second based on the OCR being able to guess 1% of those.
www.fijiwebdesign.com - web design and development and fun
Cpanel Email - Let users Register email accounts on your website upon registration
Ajax Chat - Fully browser based chat!
Reply With Quote Quick reply to this message  
Join Date: Apr 2007
Posts: 136
Reputation: dr4g is an unknown quantity at this point 
Solved Threads: 5
dr4g's Avatar
dr4g dr4g is offline Offline
Junior Poster

Re: Login Security !

 
0
  #12
Jul 10th, 2007
Thanks for your input digital-ether.
CAPTCHA is already going to be implemented to minimalise the risk of automated attacks.

The database idea, i'll go with. However you mentioned;
A simple pattern is 5 failed login attempts on a username. This is without regards to who made the attempts or from where or what IP
You didn't talk about what to do if theres 5 failed login attempts, were you agreeing with that fact that disabling user login for 15 minutes?

Cheers.
GardCMS :: Open Source CMS :: Gardcms.org
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 43
Reputation: cereal is an unknown quantity at this point 
Solved Threads: 4
cereal cereal is offline Offline
Light Poster

Re: Login Security !

 
0
  #13
Aug 3rd, 2007
Hiya,
I'm new here I've arrived here with a google train, in search of a method to limit or slow down brute force attemps.

I agree with many of you, but I also think that we can only slow down an attacker. Best thing we can do is logging the attemps.

Originally Posted by digital-ether View Post
A simple pattern is 5 failed login attempts on a username. This is without regards to who made the attempts or from where or what IP (these are factors that can be changed by the attacker), just the fact that there exists 5 failed login attempts on a single username in the last 15 minutes.
I agree with you, and probably this is the best solution, but an attacker could always write a brute force program that tries four password per username and then switch to the next username until the timeout is finished, no?

Or my guess is just fantasy?!
Reply With Quote Quick reply to this message  
Join Date: Sep 2005
Posts: 1,083
Reputation: digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice 
Solved Threads: 66
Moderator
digital-ether's Avatar
digital-ether digital-ether is offline Offline
Veteran Poster

Re: Login Security !

 
0
  #14
Aug 3rd, 2007
Originally Posted by cereal View Post
...I agree with you, and probably this is the best solution, but an attacker could always write a brute force program that tries four password per username and then switch to the next username until the timeout is finished, no?

Or my guess is just fantasy?!
Yes, an attacker could always do that. The smarter our code that looks for patterns the better. 5 attempts on a username is just an example.

A brute force works on two things, speed and probability. If you can slow down the attack, and reduce the success probability, you stop the brute force.

If a brute force can attempt a username with different passwords only 4 times, then the probability is low that it will be a success. Even if you have 10000 users, thats only 40000 attempts (assuming your user list is available to the attacker), which is has a very low probability compared to an infinite number of attempts.
www.fijiwebdesign.com - web design and development and fun
Cpanel Email - Let users Register email accounts on your website upon registration
Ajax Chat - Fully browser based chat!
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 43
Reputation: cereal is an unknown quantity at this point 
Solved Threads: 4
cereal cereal is offline Offline
Light Poster

Re: Login Security !

 
0
  #15
Aug 3rd, 2007
Yes, indeed. Thanks for the reply
Reply With Quote Quick reply to this message  
Join Date: Aug 2007
Posts: 1
Reputation: tirstan is an unknown quantity at this point 
Solved Threads: 0
tirstan tirstan is offline Offline
Newbie Poster

Re: Login Security !

 
0
  #16
Aug 9th, 2007
Just posting to thank digital-ether for the posts. Love the social based CAPTCHA example.

Spend some time researching because I want to implement this feature as well. This is what I came up with. Comments appreciated.

DB table:
CREATE TABLE `auth` (
`id` int(11) NOT NULL,
`username` varchar(40) NOT NULL,
`password` varchar(60) NOT NULL,
`email` varchar(60) NOT NULL,
`role` varchar(10) NOT NULL default '0',
`timeStamp` varchar(20) NOT NULL,
`incorrect` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

used varchar for timeStamp so I could store unix timestamp (MySQL did not like format). DateTime has too many variables to account for (i.e. what if the time is 23:50?) and is a bit of a pain to convert.
Now the Goods:
  1. function protectLogin(){
  2. Global $dbx;
  3. $protect=false;
  4. $user=$_POST['username'];
  5. $password=$_POST['password'];
  6. $query= "Select * from auth where username = '".mysql_real_escape_string($user)."'";
  7. $userQuery = $dbx->query($query);
  8. if($row = $userQuery->fetchRow(DB_FETCHMODE_ASSOC)){
  9.  
  10. $_SESSION['authorize']['id']=$row['id'];
  11. $_SESSION['authorize']['username']=$row['username'];
  12. $_SESSION['authorize']['timeStamp']=$row['timeStamp'];
  13. $_SESSION['authorize']['incorrect']=$row['incorrect'];
  14. $_SESSION['authorize']['role']=$row['role'];
  15.  
  16. if( md5($password)==$row['password'] && ($row['incorrect']!=5) ){
  17. //echo " passwords match </br>";//set session
  18. $_SESSION['authorize']['register']=1;
  19. header ("Location: ./index.php");
  20. }else{
  21. $protect=true;//incorrect password or has had 5 incorrect logins
  22. }
  23. }
  24. $userQuery->free();
  25. return $protect;
  26. }
  27.  
  28. //***********************************************************************************
  29. // this section displays email form for lost passwords shown only when login fails
  30. //***********************************************************************************
  31. function wrongPass($tpl){
  32. Global $dbx;
  33. //add variables from db
  34. $id=$_SESSION['authorize']['id'];
  35. $user=$_SESSION['authorize']['username'];
  36. $date=$_SESSION['authorize']['timeStamp'];
  37. $incorrect=$_SESSION['authorize']['incorrect'];
  38. // $ip=$_SERVER['REMOTE_ADDR'];//if you want to save the ip of incorrect logins
  39.  
  40. //echo " the unix timestamp stored is <br>".$date."<BR>";
  41. //echo " the date is ".date("F j, Y, g:i a",$date)."<BR>";
  42. $storedDate=$date+900;//if less than this increment count
  43. //echo " date plus 900 seconds ".date("F j, Y, g:i a",$storedDate)."<BR>";
  44.  
  45. $time=mktime();//current time
  46. //echo " the unix timestamp now is <br>".$time."<BR>";
  47. //echo " incorrect attempts = $incorrect <br>";
  48. //echo " the date is ".date("F j, Y, g:i a",$time)."<BR>";
  49.  
  50. $query="UPDATE `auth` SET ";
  51. if($storedDate>$time){//within 15 minutes of previous attempt
  52. if($incorrect!=5){//not already 5 increase number
  53. $query.=" `incorrect`='".($incorrect+1)."'";
  54. $query.="WHERE `id`='".$id."'";
  55. //echo $query."<BR>";
  56. $dbx->query($query);
  57. }
  58. }else{//first invalid attempt in fifteen minutes
  59. $query.="`timeStamp`= '".$time."', `incorrect`='1'";
  60. $query.="WHERE `id`='".$id."'";
  61. //echo $query."<BR>";
  62. $dbx->query($query);
  63. }
  64.  
  65. $lost=centerColumnHead("Unable to login!!!", "Please Try again Later");
  66. $lost2="<br /><br /></div> </td></tr>";
  67.  
  68. $tpl->setVariable("centerColumnContent", $lost);
  69. $tpl->setVariable("centerColumnContent2", $lost2);
  70.  
  71. return $tpl;
  72. }

What could you do with the ip address of the incorrect logins?
Last edited by digital-ether; Aug 9th, 2007 at 8:26 am. Reason: edited syntax highlighting
Reply With Quote Quick reply to this message  
Join Date: Sep 2005
Posts: 1,083
Reputation: digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice digital-ether is just really nice 
Solved Threads: 66
Moderator
digital-ether's Avatar
digital-ether digital-ether is offline Offline
Veteran Poster

Re: Login Security !

 
0
  #17
Aug 9th, 2007
Originally Posted by tirstan View Post
Just posting to thank digital-ether for the posts. Love the social based CAPTCHA example.

Spend some time researching because I want to implement this feature as well. This is what I came up with. Comments appreciated.

DB table:
CREATE TABLE `auth` (
`id` int(11) NOT NULL,
`username` varchar(40) NOT NULL,
`password` varchar(60) NOT NULL,
`email` varchar(60) NOT NULL,
`role` varchar(10) NOT NULL default '0',
`timeStamp` varchar(20) NOT NULL,
`incorrect` tinyint(4) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

used varchar for timeStamp so I could store unix timestamp (MySQL did not like format). DateTime has too many variables to account for (i.e. what if the time is 23:50?) and is a bit of a pain to convert.
Now the Goods:
  1. function protectLogin(){
  2. Global $dbx;
  3. $protect=false;
  4. $user=$_POST['username'];
  5. $password=$_POST['password'];
  6. $query= "Select * from auth where username = '".mysql_real_escape_string($user)."'";
  7. $userQuery = $dbx->query($query);
  8. if($row = $userQuery->fetchRow(DB_FETCHMODE_ASSOC)){
  9.  
  10. $_SESSION['authorize']['id']=$row['id'];
  11. $_SESSION['authorize']['username']=$row['username'];
  12. $_SESSION['authorize']['timeStamp']=$row['timeStamp'];
  13. $_SESSION['authorize']['incorrect']=$row['incorrect'];
  14. $_SESSION['authorize']['role']=$row['role'];
  15.  
  16. if( md5($password)==$row['password'] && ($row['incorrect']!=5) ){
  17. //echo " passwords match </br>";//set session
  18. $_SESSION['authorize']['register']=1;
  19. header ("Location: ./index.php");
  20. }else{
  21. $protect=true;//incorrect password or has had 5 incorrect logins
  22. }
  23. }
  24. $userQuery->free();
  25. return $protect;
  26. }
  27.  
  28. //***********************************************************************************
  29. // this section displays email form for lost passwords shown only when login fails
  30. //***********************************************************************************
  31. function wrongPass($tpl){
  32. Global $dbx;
  33. //add variables from db
  34. $id=$_SESSION['authorize']['id'];
  35. $user=$_SESSION['authorize']['username'];
  36. $date=$_SESSION['authorize']['timeStamp'];
  37. $incorrect=$_SESSION['authorize']['incorrect'];
  38. // $ip=$_SERVER['REMOTE_ADDR'];//if you want to save the ip of incorrect logins
  39.  
  40. //echo " the unix timestamp stored is <br>".$date."<BR>";
  41. //echo " the date is ".date("F j, Y, g:i a",$date)."<BR>";
  42. $storedDate=$date+900;//if less than this increment count
  43. //echo " date plus 900 seconds ".date("F j, Y, g:i a",$storedDate)."<BR>";
  44.  
  45. $time=mktime();//current time
  46. //echo " the unix timestamp now is <br>".$time."<BR>";
  47. //echo " incorrect attempts = $incorrect <br>";
  48. //echo " the date is ".date("F j, Y, g:i a",$time)."<BR>";
  49.  
  50. $query="UPDATE `auth` SET ";
  51. if($storedDate>$time){//within 15 minutes of previous attempt
  52. if($incorrect!=5){//not already 5 increase number
  53. $query.=" `incorrect`='".($incorrect+1)."'";
  54. $query.="WHERE `id`='".$id."'";
  55. //echo $query."<BR>";
  56. $dbx->query($query);
  57. }
  58. }else{//first invalid attempt in fifteen minutes
  59. $query.="`timeStamp`= '".$time."', `incorrect`='1'";
  60. $query.="WHERE `id`='".$id."'";
  61. //echo $query."<BR>";
  62. $dbx->query($query);
  63. }
  64.  
  65. $lost=centerColumnHead("Unable to login!!!", "Please Try again Later");
  66. $lost2="<br /><br /></div> </td></tr>";
  67.  
  68. $tpl->setVariable("centerColumnContent", $lost);
  69. $tpl->setVariable("centerColumnContent2", $lost2);
  70.  
  71. return $tpl;
  72. }

What could you do with the ip address of the incorrect logins?
The code looks good to me.

If you'll need an extra table to log IPs of unsuccessful attempts, you might as well have a db table that logs every single unsuccessful login attempt within a certain time period to the present. That way you can use that table to determine the number of failures on a username, as well as from a single IP, or other data etc..

Eg:

  1. CREATE TABLE `failed_auth` (
  2. `id` int(11) NOT NULL,
  3. `username` varchar(40) NOT NULL,
  4. `password` varchar(60) NOT NULL,
  5. `ip` varchar(8) NOT NULL,
  6. `time` timestamp NOT NULL default CURRENT_TIMESTAMP,
  7. PRIMARY KEY (`id`)
  8. )

Eg Queries:
  1. "SELECT count(id) FROM failed_auth WHERE username = '$username' AND time > (NOW() - 3600)"; // failed attempts in last hour for username
  1. "SELECT count(ip) FROM failed_auth WHERE ip = '$ip' AND time > (NOW() - 3600)"; // select failed attemps from a single IP in last hour

This would also allow you to retrieve other simple patterns that tell you of a brute force. Eg. Your failed authentications table is getting larger than your users table...

  1. "SELECT (count(id) > (SELECT count(id) FROM users) FROM failed_auth WHERE f.time > (NOW() - 3600)";
  2. ; // every single user made a failed attempt in the last hour? don't think so

This can determine when you want to show a CAPTCHA with your login form, or start delaying authentications for a few secs.

A less obvious pattern would be a dictionary based attack. If you see username/password start incrementing in a dictionary order, you could tell its a dictionary attack.

The table shouldn't get that big. It should stay smaller than your user's table if old rows are deleted when they expire..

I've never implemented anything like this on a live site. Its just an idea. Maybe its overkill?
www.fijiwebdesign.com - web design and development and fun
Cpanel Email - Let users Register email accounts on your website upon registration
Ajax Chat - Fully browser based chat!
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the PHP Forum


Views: 3439 | Replies: 16
Thread Tools Search this Thread



Tag cloud for PHP
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC