Anyone have an article or some ideas on how this could be done? Is limiting attempts the simplest way?
Even if you do limits, aren't these session-based? I'm guessing a cracker isn't going to respect sessions.
Anyone have an article or some ideas on how this could be done? Is limiting attempts the simplest way?
Even if you do limits, aren't these session-based? I'm guessing a cracker isn't going to respect sessions.
1 - LastLoginAttemptedDateTime
2 - LastLoginAttemptedIPAddress
3 - LastSuccessfulLoginDateTime
4 - LastSuccessfulLoginIPAddress
5 - MustChagePasswordAtNextLogin - a boolean flag to indicate they must change their password. You'll set that flag when they're recovering a password, or you've emailed them a temporary password.
6 - UnsuccessfulLoginCount - some number that your logic will use to determine how long they must wait, or if they sit in the penalty box.
7 - AccountLocked - boolean flag, some pointy haired bosses will not permit accounts to be locked out, like mine. And mine refuses to allow passwords to be one-way hashes (his words: we must be able to email the user the password they use). Depending on the security you need, the user of a locked account either has to phone up an unhelp desk, or show up in person.
8 - UserAgreementID - As you change user agreements, you'll want to keep track of what agreement the user agreed to, what day and time. This is something you'll want to log, and if you make substantial changes to the user agreement, you may want to force them to re-agree to the terms of use. You will also want to keep every version of the user agreement stashed away in a table somewhere, in case the lawyers get involved.
9 - UserAgreementDateTime - see #8
Along with a LoginTransaction table that captures attempts - both successful and not to log in, with usernames, date/time, IPaddress. This table should locked down so that a hacker can't delete entries, entries can be added, but not deleted nor changed. You'll do that with triggers ("instead of" triggers for sql server folks).
Perhaps your business logic says that a user can have 3 attempts in a 5 minute window (with no lockouts).
Your code would do something like...user has made 3rd bad attempts, set LastLoginAttemptedDateTime = Now, set UnsuccessfulLoginCount = 3.
Now the user tries to log in 1 minute later...If LastLoginAttemptedDateTime + 5_minutes < Now then log the attempt, LastLoginAttemptedDateTime = Now, reject login attempt EndIf.
If they log in successfully, log that event, set UnsuccessfulLoginCount = 0, set LastSuccessfulLoginDateTime and LastSuccessfulLoginIPAddress to the appropriate values.
Small user sets, such as the Twitter admin accounts, would not be large enough to be successful with a horizontal attack. Provided, of course, that every user has a minimum password complexity, which they did not. Even without complexity requirements, the list of simple words is still prohibitively large in most cases.
That said, if you have even one user among millions with the password "qwerty", he is certainly at risk. However, once you are at a scale prone to this kind of attack, a more sophisticated rate limiting scheme is probably required even for regular web requests.
Specifically, Fail2Ban follows auth logs for various services, and when it finds clients exceeding per-service configured limits, it adds IPTables rules that ban the offending IP address for a configurable amount of time.
Fail2Ban is packaged in many distributions, including Debian and Ubuntu, and can be compiled on just about any system. I personally use it exclusively to thwart brute force attacks on SSH, SMTP/Postfix, IMAP/Dovecot, and HTTP/Apache.
It should be trivial to add a new set of filter/jail rules for any web application that can log bad authentication attempts to a file, and then you have instant "protection" from most brute force attacks.