1

I'm working on login script for a website and I need some orientation. My concern its about security..

There are 2 things involved, the login page and the login class, and I managed security as follows..

The form inside login.php has a token and when the user submit the form (target to "php_self"), I call the class and:

  • validate the token
  • check if user is not block
  • check if password is correct with bcrypt.
  • if login fails, stored the number of attempts and datetime of the last login for that user in the db
  • if its the 2nd attempt, I put recaptcha within the form. The captcha is validated through jquery/ajax (for usability reasons), and validated again server-side in the class after submit (in case someone forces the ajax post call)..
  • if the 5th attempt fail, that account is blocked for 10 minutes.

Do you see any security weakness?

I found one and don't know how to fix it.

If fails attempts is "x" and recaptcha is required, user can click "login page" link (not refresh), and find the form without recaptcha (as attempt is 0).. I could create a Session variable "attempt", but this one can be force as well as the ajax call, right?

thanks in advance for your help

buu
  • 131
  • 1
  • 8
  • how do you know its the same user trying to login again? – Aris May 11 '13 at 19:38
  • because the user logs in with mail and pass. I've a table in the database in which I store the userid, attempts and lastlogin.. When user submits form, I check in that table.. – buu May 12 '13 at 00:13

2 Answers2

2

One security issue I see is when a robot is creating random mail and passwords and keeps logging in. Since the email is different every time, you don't know its the same 'robot' and it will keep your webserver busy and make it slower.

To solve this:

  1. You can always have CAPTCHA
  2. You can get the caller IP and enforce your rules based on IP, not email. When this IP tries several time you can block it on the firewall.
Ladadadada
  • 490
  • 3
  • 15
Aris
  • 3,804
  • 1
  • 31
  • 33
  • I'm actually working on xampp and don't know much about firewall.. but I'll search about it, thanks! – buu May 13 '13 at 04:28
  • blocking an IP is done by your administrator. On the programming side, captcha will help in this case. – Aris May 13 '13 at 05:03
  • but I can block user login based on the ip, checking its attempts against the database.. right? – buu May 13 '13 at 14:26
  • but the attacker will keep trying to login, and only in the server side will you know his IP to stop him. in a brute force attack, he will keep your server busy and slow. – Aris May 13 '13 at 15:02
  • thanks for answering.... ok, so that can't be done server side with php.. then I have 2 questions, 1) login script should only check user/password, token and captcha? 2) if ip must be checked outside php.. hostings already provide that service? – buu May 13 '13 at 21:25
  • captcha will prevent brute force attacks, user/password can be checked as you designed.and maybe you won't need ip checking, because attack will be stopped on the client side by captch and not stress your server. – Aris May 14 '13 at 04:46
  • Perfect Aris, I'll continue and learn more about blocking late.. I've found a very useful overall thread about security here:http://stackoverflow.com/questions/549/the-definitive-guide-to-forms-based-website-authentication/477578#477578 – buu May 14 '13 at 22:18
  • I'm experiencing some troubles now with recaptcha and may be you can help me.. Recaptcha is working great validating through ajax or server side.. But for some reason, when i use both, recaptcha check function returns true on ajax and false on php after submiting.. I don't undestand why.. if i remove the client side, returns true.. ¿¿?? – buu May 14 '13 at 22:22
  • found something here.. http://stackoverflow.com/questions/9227512/recaptcha-why-cant-i-check-the-same-result-twice – buu May 15 '13 at 16:42
  • great. if you have more issues, you can open a new question. – Aris May 17 '13 at 10:57
1

The biggest problem with a scheme like this is that you are blocking (or CAPTCHAing) the user rather than the IP address. This opens up a vulnerability and doesn't stop brute forcing:

  1. Brute-force bots can have two guesses for each account without any CAPTCHA or blocking. So the bot tries 'Password' and '123456' on every account on your system and succeeds probably 2% of the time. You want to stop this bot long before it gets two guesses on every account. Especially if you're using bcrypt which is pretty expensive in CPU terms.
  2. Malicious pranksters can lock out any user they know the email address for simply by attempting to login as that user 5 times every 10 minutes.

Note that blocking IP addresses comes with its own set of false positives and false negatives. Legitimate proxy servers and bot nets mean that blocking IP addresses can lead to problems. It does solve 90% of your brute-force problems.

CAPTCHA also comes with its own set of false positives and false negatives. I know I have trouble reading plenty of ReCAPTCHA images and I've seen bots attacking my systems solving ReCAPTCHA better than I can. I don't bother with CAPTCHA at all any more except for the placebo effect it has on my customers.

You say:

user can click "login page" link (not refresh), and find the form without recaptcha (as attempt is 0)

Why is this? If the attempt count is stored in the database, why does clicking that link change the attempt count?

Does the attempt count have an automatic timeout? Does a successful login reset it?

A brute force bot may not even notice your session-based blocking if you implemented that. Sessions are based on cookies and unless your login form requires something from the session, bots won't even send that cookie until after the login. Even if it is required, a bot can get a new, unblocked session cookie whenever it wants by not sending that cookie.

Ladadadada
  • 490
  • 3
  • 15
  • good point on the issue of blocking users after x login attempts fails (brute force and malicious pranksters).. So you think the way to go is blocking the ip? using a function like this one below and storing the return would be a better approach? http://stackoverflow.com/a/3358212/1736512 || The answear to your question on "login page" is because after user submits the form (with his email), I call the login process class and retrieve the number of attempts, which by the way, sounds pointless right now.. – buu May 13 '13 at 04:21