In a nutshell:
A client enters valid user name, but an invalid password. After a
number of failed attempts, the account should be locked.
I realize that this means patching the particular auth module so that
it keeps tabs on all failed attempts, and also to add logic to handle
blocking of the user. Blocking might be changing an attribute in ldap,
removing a line from htacces or changing a record in mysql. This
depends on what type of auth module is in use.
In this particular scenario, the action is to block the user, but
there could be other actions. For instance notifying an admin by mail
or sms, logging to a database etc.
Obviously this is not trivial, but I thought one idea would be to have
some "standard" way of notify other parts of Apache each time a failed
attempt occurred. In my (limited) view of Apache, I figured something
like this:
0. Client submits a uid/pwd to a protected site
1. The url is protected by mod_auth_foo, which tests the uid/pwd
2. mod_auth_foo finds that the pwd is invalid for that uid
3. mod_auth_foo calls 'ap_user_failed_attempt (uid)' or starts a
failed_attempt handler or something. I have not clue about this.
4. ap_user_failed_attempt() is a module which does the actual user
tracking, by whatever means is needed. It also knows what action to
perform (ie if and when to block the user, sending admin mail or
something ...).
So all that is required of the used mod_auth module would be to call
ap_user_failed_attempt().
Maybe this already exists somewhere, mod_perl perhaps?
Any thoughts and ideas would be much appreciated!
> In a nutshell:
>
> A client enters valid user name, but an invalid password. After a
> number of failed attempts, the account should be locked.
Provides any mischief maker with an instant denial-of-service attack.
> In this particular scenario, the action is to block the user, but
> there could be other actions. For instance notifying an admin by mail
> or sms, logging to a database etc.
>
> Obviously this is not trivial,
Seems easy enough to me as stated; just that it rates to create as
much of a problem as it solves.
And 'thanks' to the widespread availability of open proxies on the
internet nowadays (the spammers are already making enthusiastic use of
them), any attempt to confine the blockout to a particular IP could be
easily circumvented.
>I have been looking for a clever way to limit number of retries when
>using basic authentication. As of now, applying brute force methods to
>[...]
>Any thoughts and ideas would be much appreciated!
We use this not-so-expensive solution and are a satisfied customer:
http://www.howlingfrog.com/products/apache/mod_hackprotect/
++ralph
> We use this not-so-expensive solution and are a satisfied customer:
This is a technical discussion group. Wouldn't you be willing to
at least sketch out the working principle, and address how it deals
with the obvious issues?
Two things immediately strike me:
1. Since it says it does its blocking per-IP, any serious attacker
would simply get themselves a list of open HTTP proxies, of which
there are many thousands on the 'net, and work via those.
2. when users access the web from behind a cache proxy, as they do at
quite a number of major ISPs as well as from some proportion of
educational campuses for example, it only takes one mischief maker to
block the access for all the other users of the same cache.
cheers
Unfortunately this is for Apache 1.3 only and... well, it is not a
free-speech solution.
Yup, but then again the mischief needs to know valid user names. On
the other hand, the point is that blocking may be just *one*
action. Everything for just separate logging to automatic CIA
notifications should be possible.
But, yes, I agree there are some issues. But, imho, the gaping
brute-force-guessing issue is a bigger problem -- and lots of
companies have silly security rules which enforces
max-number-of-retries and such which rules out basic authentication
with apache.
>> In this particular scenario, the action is to block the user, but
>> there could be other actions. For instance notifying an admin by mail
>> or sms, logging to a database etc.
>>
>> Obviously this is not trivial,
>
> Seems easy enough to me as stated; just that it rates to create as
> much of a problem as it solves.
>
> And 'thanks' to the widespread availability of open proxies on the
> internet nowadays (the spammers are already making enthusiastic use of
> them), any attempt to confine the blockout to a particular IP could be
> easily circumvented.
Blocking of IP was not my main concern. I was more thinking along the
lines of blocking a certain user, maybe for a specific time. Depending
on where the user databas is, this must of course be done in a
specific way for each auth-module. Besides, in a controlled
environment such as an intranet/vpn, DOS is pretty much a non-issue as
well.
Since I have no clue where to start digging, I would like some
technical input of how to go about it. As I see it, mod_auth_* module
need only to put the failed user name somewhere on the request memory
so that the actual mod_block_user (or whatever) can do its thing.
> > And 'thanks' to the widespread availability of open proxies on the
> > internet nowadays (the spammers are already making enthusiastic use of
> > them), any attempt to confine the blockout to a particular IP could be
> > easily circumvented.
>
> Blocking of IP was not my main concern.
I wasn't exactly meaning to "block the IP"; I was taking the reasoning
onwards from the observation that "blanket blocking of a user name
means an easy denial of service for that user", but showing that the
initially attractive option of tying the block to a specific IP
wouldn't really solve the problem either, for the reason I gave.
> I was more thinking along the
> lines of blocking a certain user, maybe for a specific time.
Actually if you could slow down the response to bad credentials, you
might make it impractical to brute-force enough different passwords in
a realistic time, while still permitting bona fide access without much
delay. Disclaimer: I haven't tried this in practice myself, though it
sounds at least a plausible principle; I haven't seen it discussed
more than superficially either (this itself surely carries some kind
of message? - but maybe someone who's got a working solution will be
willing to discuss it here, and then I'll happily defer to their
expertise).
> Besides, in a controlled environment such as an intranet/vpn, DOS is
> pretty much a non-issue as well.
Well, this here usenet group has WWW in its name - it isn't really
on-topic to deal with intranet situations. But evidently this
intranet is considered insecure enough to need defending against
password cracking attacks, so just why isn't denial of service an
issue too, riddle me that?
good luck
In article <Pine.LNX.4.53.03...@lxplus007.cern.ch>, Alan J. Flavell wrote:
>
> Actually if you could slow down the response to bad credentials, you
> might make it impractical to brute-force enough different passwords in
> a realistic time, while still permitting bona fide access without much
> delay.
It might be possible to adapt the Apache::SpeedLimit module from the
book _Writing Apache Modules with Perl and C_ to this purpose. The
module itself is designed to compute the number of accesses over a
period of time (per minute, in the example), and if that number exceeds
a set value access is denied. There's a grace period, so setting it
low enough might be able to do what the OP desired. (The module could
probably be modified to enforce the speed limit only when the HTTP
response would be 401, so initial logins may experience a delay but
subsequent accesses would be undelayed.)
- --keith
- --
kkeller...@wombat.san-francisco.ca.us
(try just my userid to email me)
alt.os.linux.slackware FAQ: http://wombat.san-francisco.ca.us/cgi-bin/fom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iEYEARECAAYFAj8AxswACgkQhVcNCxZ5ID+XDwCfWvfJXXOUaSYkyF02kFiPhC2X
gAkAnR7rZ0NIzAqi+cdx+QObPWW8KNxG
=9gTR
-----END PGP SIGNATURE-----
[ ... Agreed ... ]
>> I was more thinking along the lines of blocking a certain user,
>> maybe for a specific time.
>
> Actually if you could slow down the response to bad credentials, you
> might make it impractical to brute-force enough different passwords
> in a realistic time, while still permitting bona fide access without
> much delay. Disclaimer: I haven't tried this in practice myself,
> though it sounds at least a plausible principle; I haven't seen it
> discussed more than superficially either (this itself surely carries
> some kind of message? - but maybe someone who's got a working
> solution will be willing to discuss it here, and then I'll happily
> defer to their expertise).
Now we're talking!
Adding increasingly slower response times would indeed solve the
actual issue of brute force hacking, and at the same time completely
sidestep the whole banning/blocking issue.
Now of course the problem is keeping records of failed attempts
between requests (and across multiple apache
child-processes/threads). As I see it, the easiest way to handle it is
for mod_auth_whatever to add the username to apaches internal request
struct and thus defer the action (slowing down the response) to
another module, say mod_slowdown or something.
I would like some opinion on this approach or maybe some pointers
where to start digging. For instance, where (if at all possible) can
mod_auth_* push the failed username so another module can get a look
at it?
It's a good idea, and I suppose using mod_perl would be the smartest
way to do a proof-of-concept solution.
After reading a bit about handlers in mod_perl, here is my outline:
Create a mod_delay module in the Authen-phase and add it after the
true mod_auth entry in httpd.conf. Make sure mod_auth is
non-authoritive so apache will run the next module (mod_delay) when
the attempt fails (DECLINED). Now we know that the http response is
401 and we also know the user name, so just up the invalid-retries
count for this user and sleeps for x^nretries seconds.
The actual job with keeping the nretries info alive could be done lots
of ways (files, db etc), so it's a non-issue I guess.
Thoughts?
> It's a good idea, and I suppose using mod_perl would be the smartest
> way to do a proof-of-concept solution.
Caution: this is still off the top of my head, I haven't thought it
through in detail...
Based on what you're writing, it looks as if you're already on the way
to a production solution - to be honest, if I was just aiming for a
proof of concept trial, I reckon I would define a CGI script to be my
ErrorDocument 401, and do the work in the CGI script.
That way, I could play around with the options in a fairly stand-alone
way without having to mess with the server itself or any persistent
processes.
Indeed you'd probably want to keep some persistent data, but that
could be done in a database (even in a flat file etc.).
Efficiency is no big issue IMHO, since the code would only be invoked
after a failure. If an attacker could slow the error handling down by
hitting it harder, then so much the better ;-) as long as it didn't
too adversely affect bona fide access.
It'll be interesting to hear the results of whatever scheme is tried
out. As I say, I found relatively little practical experience
reported when I tried some plausible web search terms.
[ ... mod_auth_slowdown ... ]
>
>> It's a good idea, and I suppose using mod_perl would be the smartest
>> way to do a proof-of-concept solution.
>
> Caution: this is still off the top of my head, I haven't thought it
> through in detail...
It just struck me, using a slowdown approach like this makes it, even
easier to perform a DOS attack on the server. Just spawn a couple of
'wget joe:pwd@http://host' in a loop and the whole site will be
unavailable for *everyone* since each apache process will be in a
sleep() state. :-(
Unless I am mistaken, this makes the user-banning approach look much
better. At least then, only a specific account is affected, not the
whole server.
> It just struck me, using a slowdown approach like this makes it, even
> easier to perform a DOS attack on the server. Just spawn a couple of
> 'wget joe:pwd@http://host' in a loop and the whole site will be
> unavailable for *everyone* since each apache process will be in a
> sleep() state. :-(
You could try combining it with mod_throttle
> Unless I am mistaken, this makes the user-banning approach look much
> better. At least then, only a specific account is affected, not the
> whole server.
Nevertheless, for the affected user it represents a denial of service
over which they could have no control.
I've tried to make it clear all along that my answers are somewhat
speculative and YMMV. As I pointed out, web search did not produce
any definite indication of a robust solution for the original
question, nor do I have direct experience of doing anything similar
myself, so I'm only throwing out possible ideas, which might or might
not turn out to be practicable.
Nevertheless, I think I have enough expertise to understand that some
of the suggestions offered on the thread were fatally flawed, which
was why I got involved in the first place. Hope this helps.
--
"The operator has a long-standing problem with short formations" -
news report about a train service - translation: the operator
provides a short train, and the travellers get a long stand.
Perhaps in some combination that was not obvious to me. Besides I am
looking for a Apache 2.x solution.
>
>> Unless I am mistaken, this makes the user-banning approach look much
>> better. At least then, only a specific account is affected, not the
>> whole server.
>
> Nevertheless, for the affected user it represents a denial of service
> over which they could have no control.
After some more pondering, I think the only realistic option is to use
temporary user-banning. That is, simply return 401 regardless of a
valid password or not once we figure out that a certain user has had x
number of consecutive failures.
Essentially add mod_check_banned before mod_auth_x, and
mod_do_banning;
1. mod_check_banned: If (still) banned, return 401
2. mod_auth_*: Do the authentication. Authoritative must be off
3. mod_do_banning: If mod_auth_* failed: If nfailed[user]++ >
max_retries, temporary ban the user. Return status to client.
In this case, a DOS:er need to know (a) a user name and (b) that
banning is in fact used, something requiring lots of inside
information.
But ...
I just read some more about apache handlers and as far as I
understand: In the authen-phase, once a user is found and the supplied
password is invalid, the request is immediately returned, ie no more
phases or modules gets executed! No matter if Authoritative or not.
I thought that using 'Authoritative off' would let other modules get a
stab at the authentication. Or is there some other way to get a look
at the status right after mod_auth_* has decided that the user is
unathorized?
This kinda puts and end to this nice idea :-(