[OWASP_PHPSEC] isBruteForce ?

rahul chaudhary rahul300chaudhary400 at gmail.com
Thu Sep 5 06:35:27 UTC 2013

Your point is very clear and sound and you are correct. This definitely can
be done and is valid. Thanks. However we have to keep in mind that all the
values must be set by developers and they are free to choose any value...so
we have to check of the value they set are consistent with our application.
e.g. bruteForceLockTimePeriod must always be less than bruteForceLockAttempt

Your second point is also very good. Returning number of attempts gives us
the power to remove false positives. But we have to customize it a bit in
order to make it more usable...first thing that comes to my mind is to
provide the developers to set these conditions as to what numbers they
consider what...e.g. 3 attempts is "low" and 5 attempts is "high"....also
these numbers must be consistent to "Total count". e.g. if developer sets
total count as 100, then he probably expects 10 as "low" and if we hardcode
"3" as low then thats a problem.

For testing we are using PHPUnit as you can see in the test folder.....you
can use this to test your logic and outputs... :)

Since things are getting confusing, here I have defined a vague outline of
what me and Shivam thinks:
We will have these variables:
bruteForceLockTimePeriod: This variable defines that a normal request must
be after the specified time. e.g. if this value is 5 then in normal
operations, two consecutive requests must be after 5 seconds of the
previous request.
bruteForceLockAttempt: This variable keeps track of total login attempts
made within bruteForceLockTimePeriod. So, if this value is exceeded and the
"bruteForceLockTimePeriod" has not passed, then it is a brute force.
bruteForceLockAttemptTotalTime: This variable defines that within this time
period, a certain number of login attempts must be made. e.g. if this value
is 25, and the "Total Count" is 5, then only 5 login attempts must be made
in 25 seconds.
Total Count: This variable keeps track of total login attempts. This value
is resetted after "bruteForceLockAttemptTotalTime" has expired.

Note: Please note that "bruteForceLockTimePeriod" and "bruteForceLockAttempt"
works together. And, "bruteForceLockAttemptTotalTime" and "Total Count"
works together.

So, essentially brute force is flagged when:
1) More than "bruteForceLockAttempt" these many attempts are made
within "bruteForceLockTimePeriod"
this time period.
2) More than "Total Count" these many attempts are made within "
bruteForceLockAttemptTotalTime" this time period.

The difference between the two conditions is that...the first one restricts
to have too many failed login attempts in a short span of time.
The second one is too restrict too many failed login attempts within a long
span of time...because a bot may be silently trying to crack the password
by waiting for some time before making two consecutive login attempts.

Now the implementation,
1) bruteForceLockTimePeriod must always be less than bruteForceLockAttempt
2) bruteForceLockAttempt must always be less than "Total Count"
3) Since "Total Count" would be same as "bruteForceLockAttempt" for some
time, we can use this variable to be returned instead of boolean, so that
the developer can have a much better understanding of how severe the attack
is. e.g. 4 is returned, then the developer will know that total of 4 false
login attempts have been made. this way he/she can categorize their system.
e.g. they can set that for more than 6 attempts send an email but for less
than 6 attempts, just record this even in the logs. Actually this
functionality must go in the "Framework".
4) We need to categorize the value returned from brute force function
according to "Total Count". For this we can define percentage. So the
developer will have to choose above how much percent he should consider
severe. e.g. below 10% do nothing, 10-30%, record in logs....more than 30%,
send an email to admin...for more than 80%, warn the user etc.

More suggestions are welcome.. :)

On Wed, Sep 4, 2013 at 6:04 AM, Shivam Dixit <shivamd001 at gmail.com> wrote:

> Hello rahul,
> Thanks. Nice point.
> However I am assuming that a real user *cannot* make two consecutive
> requests *within 1 second* so I set the value of bruteForceLockTimePeriod to
> 1 sec. Because once the request is sent, he will have to wait for reply and
> then type in password again and then again make a request, so essentially
> this whole process will require more time than 1 second for a real user
> (just an assumption, correct me if I am wrong).
> Secondly I am defining bruteForceLockAttemptTotalTime to 25 which means
> that if 5 consecutive attempts are carried out within 25 seconds then it is
> also brute force.
> I have added FIRST_LOGIN_ATTEMPT to implement this funcitionality in an
> efficient way. FIRST_LOGIN_ATTEMPT will help us to determine which requests
> will be considered in a group. For example :
> Total count = 0
> I make a request at 0th second.     //I will store first login attempt
> time.
> Total count = 1
> then a request at 2nd second.      //By passing the first condition to
> check BruteForce.
> Total count = 2
> another at 4th second.
> Total count = 3
> and so on..... my condition, apart from checking time between two
> consecutive conditions is :
> if total count is less than  5
> update total count
> update last_login_attempt
> return false
> if total count == 5 and *present request time minus first request time*is
> *less than 25* seconds then it will be brute force.
> else
> I will update *first login attempt time as time of this request*, and
> update other values as you were doing before and return false.
> Essentially I am trying to group requests, so that I can find of time of
> the first request of the group and the last request of that group , if that
> is higher than our allowed time then we will flag brute force. Groups will
> be made only when request are done in short time. Otherwise we will reset
> our group. Hence we require first login attempt and keep updating that value
> Result : This filter will reduce lot of false positives as well as
> increase time of brute force attempts to such extent that it becomes
> practically not feasible to make a successful brute force attempt.
> PS: I have fixed a small condition after I made a pull request, now my new
> conditions are exactly what I am looking for.
> To make things more practical :
> Instead of isBruteForce function just returning boolean, can we return an
> integer to define level of an attack ? Say return 0 , return 1 or return 2
> , where 0, 1, and 2 define the level of attack.
> Explanation:
> return 'x' :
> x:
> 0 : not brute force.
> 1 : two attempts made within 1 second (or whatever value).
> Result : Developer must show captcha if he recieves 1.
> 2 : *No of attempts* made are very high in short time (5 attempts within
> 25 seconds or whatever value).
> Result : He must block account temporarily for 15 minutes.
> Benefit of above approach to isBruteForce ?
> We will have more customized control.
> Suggestions are welcome. Rahul please take a look at my update code :
> https://github.com/shivamdixit/phpsec/commit/c0fcc9c8c244d028ba9102a8492bdaac7df12073
> Also I am new to this library kind of things. So please advice me that how
> should I test my code without having any view of application or complete
> application to run and test ? Syntax check as well as how to check if my
> application is logically correct.
> On Wed, Sep 4, 2013 at 12:26 AM, rahul chaudhary <
> rahul300chaudhary400 at gmail.com> wrote:
>> Intresting point...nice dude.. :)
>> but let us see....4 attempts in 5 sec...and that would be the bot
>> limit....remember, we are not trying to prevent the bot to NOT guess the
>> passwords...we want to minimize the attempts they can make so that password
>> guessing is not possible in real time...
>> The max attempt is actually limiting the bot to guess only that much
>> password in the "two consecutive password time limit".
>> But your point actually brings my attention towards one thing...suppose
>> the time between two attempts is very large...say 5 sec..and the max
>> attempts are also large...say 1000...then the bot can make 999 requests in
>> 4.99 sec...in which case it is a problem...
>> But if we go by your solution, then for the legit cases, we will get a
>> lot of false positives...here is how....two consecutive attempts are made
>> in 5 sec...so that would flag a brute force, when actually its not...its
>> just two attempts...no need to worry the developers for this small case.....
> --
> *Cheers,*
> *Shivam*

Rahul Chaudhary
Ph - 412-519-9634
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.owasp.org/pipermail/owasp_php_security_project/attachments/20130905/c268d60c/attachment-0001.html>

More information about the OWASP_PHP_Security_Project mailing list