2

I am creating a lgoin time out. I have everything else working perfectly fine on my code. Here is my specification for the timeout:

  • If a user enters a password wrong 5 times within a 24hr period, lock them out for 48hrs.
  • If a user enters the password correctly, within the 5 attempts and 24hr period, reset their attempts.

I still need it to time the user out for 48 hours, and display a message letting the user know they have been timed out. If you could help me out with this I'd be really grateful. Here is the code snippet:

Here is a snippet of the code for the login attempt:

        if (!$pw_ok)    {
            if (isset($_SERVER["REMOTE_ADDR"])) {
                    $str_RemoteHost = $_SERVER["REMOTE_ADDR"];
                } else {
                    $str_RemoteHost = '';
                }

                $qry_WriteToDatabase = "    INSERT INTO cms_user_login_attempts
                                        (
                                            cula_user_id,
                                            cula_date_time,
                                            cula_remote_host,
                                            cula_attempt_count
                                        )
                            VALUES          (
                                            " . $db->SQLString($row->user_id) . ",
                                            Now(),
                                            " . $db->SQLString($str_RemoteHost, true) . ",
                                            'cula_attempt_count'
                                        )";
                $db->query($qry_WriteToDatabase);

                $qry_UpdateCount = "    UPDATE 
                                            cms_user_login_attempts
                                        SET 
                                            cula_attempt_count = cula_attempt_count + 1
                                        WHERE 
                                            cula_user_id = " . $db->SQLString($row->user_id) . " ";
                $db->query($qry_UpdateCount);                           



                $qry_CheckDatabase = "  SELECT 
                                            CASE WHEN count(*) >= 5 THEN 0 ELSE 1 END as allowed_login 
                                        FROM
                                            cms_user_login_attempts
                                        WHERE
                                            cula_date_time >= DATE_SUB(CURRENT_TIMESTAMP, interval 48 hour) 
                                        AND 
                                            cula_user_id = " . $db->SQLString($row->user_id) . "";
                $rs_CheckDatabase = $db->query($qry_CheckDatabase);

                if (! (isset($qry_CheckDatabase) && $qry_CheckDatabase)) {
                $errors->defineError("invalid_user_pass", "Bleh.", array("username","password"));
                }



        }

edit: I have updated the question and code.

  • 1
    Your question lacks specificity. – Drew R Jan 05 '15 at 13:09
  • *"if a user enters the correct password within the 5 attempts, i want the attempts to reset for that user."* - UPDATE the row(s) in question with a `WHERE` clause. – Funk Forty Niner Jan 05 '15 at 13:13
  • What specifically isn't working? You've presented us with a description of what you want to do, but you haven't explained where you're stuck. – David Jan 05 '15 at 13:14
  • at first glance why is `$_SERVER["REMOTE_ADDR"]` involved? a) its unreliable and b) disconnect from the isp to refresh ip address and try again – andrew Jan 05 '15 at 13:15
  • @andrew, to give him the benefit of the doubt, there's no logic in the code that implies he's looking at the REMOTE_ADDR to determine if it's the same user. He could want it there for logging purposes only. – trpt4him Jan 05 '15 at 13:17
  • create a log table, in that table maintain the attempts of invalid logins.. and update user table with flag (status = 0), and then runs a cron file.. – Arun Jan 05 '15 at 13:17
  • I have added what i need help with at the bottom of the question – PHP Learner Jan 05 '15 at 13:17
  • If I understand correctly, you're trying to figure out the actual, plain login part right now. I would recommend you work out the login piece first, then add this extra check in later. Seems to me you're doing things out of order and it's adding to confusion. – trpt4him Jan 05 '15 at 13:18
  • @trpt4him my login piece is fine, this is just a snippet of the code. My login page is able to check if username/password is fine, this is just an addition to my portal i want to make – PHP Learner Jan 05 '15 at 13:19
  • Gotcha. In that piece of code where it validates the username and password, you're going to need to add another part that does a SELECT COUNT from your `cms_user_login_attempts` table where the user_id is the one trying to login and the date is in the last 24 hours. If that count is > 5, you have a bad attempt. – trpt4him Jan 05 '15 at 13:21
  • Do you want that table to include ALL login attempts, or just bad ones? If the latter, you could delete all attempts for that user once they have logged in successfully. – trpt4him Jan 05 '15 at 13:23
  • I only want it to log the bad attempts, I have a login history table already in different part of my code. The SELECT count is a good shout, but then it will only be select the user_id and ignoring the timestamp of the bad login attempt. I still want it to check if the 5 bad attempts are within the 24hr period. – PHP Learner Jan 05 '15 at 13:28
  • Please check these link You will get an idea about that.http://webcheatsheet.com/php/blocking_system_access.php, http://stackoverflow.com/questions/2090910/how-can-i-throttle-user-login-attempts-in-php – Lakhan Jan 05 '15 at 13:29
  • Actually there are too many methods of do it. With the help of session, Cookies and database(Create new table in database). – Lakhan Jan 05 '15 at 13:30
  • @trpt4him Hello, if you are still able to help me, i have updated my code. Having a little trouble with my code, it is adding the failed attempt to the database, but it is only update one row for that user, the rest of the rows are not being updated – PHP Learner Jan 08 '15 at 16:12

4 Answers4

2

You need to save the login attempt before the password verification

if (! (isset($pw_ok) && $pw_ok))

Therefore, add a boolean field called cula_login_success to indicate if the password verification was successful.

And then query the number of failures in that date, the SQL should be something like this:

$qry="select cula_user_id,count(*) from cms_user_login_attempts where DATEDIFF(cula_date_time,NOW())<=2 and cula_user_id=".$db->SQLString($row->user_id)+" and not exist(select cula_user_id from cms_user_login_attempts where  DATEDIFF(cula_date_time,NOW())<=2 and cula_user_id=".$db->SQLString($row->user_id)+" and cula_login_success=1) group by cula_user_id having count(*)>5";

This query should return an empty set, if it doesn't - then it means your user tries to login unsuccessfully more than 5 times, in 2 days, with no successful logins in between

Uri Goren
  • 13,386
  • 6
  • 58
  • 110
  • Could you give me an example of the boolean field cula_login_success – PHP Learner Jan 05 '15 at 15:00
  • boolean means `True`/`False` (alternatively `0` or `1`) – Uri Goren Jan 05 '15 at 15:05
  • Hello, if you are still able to help me, i have updated my code. Having a little trouble with my code, it is adding the failed attempt to the database, but it is only update one row for that user, the rest of the rows are not being updated. – PHP Learner Jan 08 '15 at 15:48
  • Please choose an answer, and post another question. People reading this page in the future will not know what's going on – Uri Goren Jan 08 '15 at 19:03
1
table
--------------------------
user_id | attempts | datetime

Everytime login fails you add one to attempts and update datetime. When the user logins correctly you update the db and set attempts to zero . if attemts is equeal or greater than 5 you first check the datetime to see if its greater than 24 hours if so you login and reset attemts else you show a message and dont try to login.

Poorya Mohammadi
  • 751
  • 1
  • 8
  • 18
  • this is exactly what I want to do but i am having troubles actually writing it in code, could you help me with this? – PHP Learner Jan 05 '15 at 13:53
  • first create a new table or adjust the one you have. Thens start writintg some code. i can help you but i am not going to write it for you. – Poorya Mohammadi Jan 05 '15 at 13:57
  • Ok I have adjusted the table, it now has fields such as cula_id, cula_user_id, cula_date_time, cula_remote_host, cula_attempt_count. I have it now so that if a wrong password is input, it now writes that to the database, logging the user_id. – PHP Learner Jan 05 '15 at 14:48
  • Nothing is being written into the cula_attempt_count, just need to figure out how to get the program to count the login attempt and put it into the database. – PHP Learner Jan 05 '15 at 14:49
  • You need to upate the row with a given user_id. like: update tablename set attempt=attempt+1 where user id=?; – Poorya Mohammadi Jan 05 '15 at 15:43
  • or insert it first if it does not exist – Poorya Mohammadi Jan 05 '15 at 15:43
  • Hello, if you are still able to help me, i have updated my code. Having a little trouble with my code, it is adding the failed attempt to the database, but it is only update one row for that user, the rest of the rows are not being updated. – PHP Learner Jan 08 '15 at 15:40
0

In your table, you should be recording whether the attempt was successful or not. Then, before loading the form again, check if the user has 5 unsuccessful attempts within the last 24 hours and decide whether to lock the account or let the user try again.

Yavor
  • 675
  • 4
  • 20
  • Atm I have it so that it is recording the login attempt if it is bad. I just need the code to check the amount of attempts within a 24hr period. And reset the attempt count if the password is correctly put in within 5 tries. – PHP Learner Jan 05 '15 at 13:44
0

DO NOT Do that.... If someone will quess user name, he can easly DDOS the person. Its better to delay the login. Like - if wrong login count is hight (more than 5 for you) before checking the login use sleep for 10 seconds. This will sloow the atacks but still allow real user to log in. If there is many failed logins (20-30) then block account for several minutes, and ban ip for hour or so. That way your users would be able to login, and yet atackers would be blocked.

Seti
  • 2,169
  • 16
  • 26