i'm developing a PHP web application and the main focus of the app is security. Until now i've stored the authentication data into 2 cookies:
- one cookie for a unique hash string (30 chars)
- one cookie for a unique id (the primary key of the mysql database table which holds the cookie info and user id)
Db tables look like this:
- Users (user_id, username, password)
- Cookies (cookie_id, user_id, hash, time, ip)
When a user visits the page the app checks for existing cookies (cookie check) on the client and compares them to the database table Cookies. If the hash string and the id match, the session is extended and if they don't, the session is destroyed (if exists) and the user is prompted to login. It also checks if the session expired by comparing the current time stamp to the time stamp of the last activity.
When the user logs in a hash strings is generated and stored in the database (the current time stamp and IP is also stored). The primary id of the newly generated row and the hash string are then stored into two cookies and used for authentication.
I would like to implement additional security to prevent dictionary or brute force attacks, by throttling the login and cookie check attempts. I'd like to achive that when the user fails N times to login or to validate cookies that he gets blocked for 20 minutes. But if i do this using the IP i would potentially block every user using that IP.
I could lock the specific user account when there are more than X failed attempts, but the problem is when the attacker doesn't supply a valid username (so i would have to block the whole IP for N minutes).
The login form has also a captcha check, but that just slows down a attack (nothing compared to denying login attempts for X minutes).
- Is there any other way of denying login attempts without blocking out the whole network using that IP?
- Should i bother with denying login attempts when there are N failed cookie checks?
- If the users cookies are stolen, i use the IP in Cookie table to prevent reusing it, so the cookies are usable only from the same IP as the users. Is this secure or should i do it somehow else?
Thanks in advance,
PS: all passwords in database are hashed, the cookie values are encoded before used in a db query (so injections aren't possible).