[rt-devel] Avoiding Brute Force attacks on rt-2-0-15
Warnke, Andreas
Andreas.Warnke at 3SOFT.de
Wed Feb 5 11:58:47 EST 2003
Hi there,
For RT2-0-15, there is no protection from brute force attacks on either
the user/pass combination or on the cookie-strings.
Here is a solution:
Exchange the webrt/autohandler script by the lines below to limit the
number of rejected logins to 10 per minute.
(And be sure, you have installed Cookie::Cookie from cpan)
I would appreciate comments.
Kind Regards
Andreas
--
Andreas Warnke
3SOFT GmbH, Frauenweiherst. 14, 91058 Erlangen
Tel.: +49-9131-7701-274 mailto:Andreas.Warnke at 3SOFT.de
Fax: +49-9131-7701-333 http://www.3SOFT.de
------------------------------------------------------------------------
----------
%# $Header: /pro/CVS/rt/rt-2-0-15/webrt-rtee/autohandler,v 1.1
2002/11/07 10:59:31 anwa2219 Exp $
<& /Elements/Footer, %ARGS &>
<%INIT>
my $current_time = time;
$m->{'rt_base_time'} = $current_time;
# ----------------------------------------
# added by Andreas Warnke
# 'Period' denotes the end of the current observation interval
# 'Attacks' is the number of rejected login tries
# during the current observation interval
# ----------------------------------------
my $ACache = $m->cache;
my $period = $ACache->get('Period') || 0;
my $attacks = $ACache->get('Attacks');
# ----------------------------------------
# ----------------------------------------
# added by Andreas Warnke
# Next observation interval?
# (And initialization)
# ----------------------------------------
if ( $period < $current_time ) {
$period = $current_time + 60;
$attacks = 0;
$ACache->set('Period',$period);
$ACache->set('Attacks',$attacks);
}
# ----------------------------------------
# ----------------------------------------
# added by Andreas Warnke
# AttackEncountered?
# ----------------------------------------
sub AttackEncountered {
my $ACache = $m->cache;
my $attacks = $ACache->get('Attacks');
$attacks += 1;
$ACache->set('Attacks',$attacks);
}
# ----------------------------------------
#if it's a noauth file, don't ask for auth.
if ($m->base_comp->path =~ '^/+NoAuth/') {
$m->call_next();
$m->abort();
}
# ----------------------------------------
# added by Andreas Warnke
# The complete database is locked
# if there have been more than 10 attacks.
# Q: Why not just disable the login-sequence
# A: There are 2 types of brute force attacks:
# 1) Brute force on the user/pass combination
# 2) Brute force on a valid session cookie
# So: Neither may be served if the system
# is under attack
# ----------------------------------------
elsif ( $attacks > 10 ) {
$m->comp('/Elements/Login', Error => 'Sorry. RT2 is locked for
60 seconds.', %ARGS);
$m->abort();
}
# ----------------------------------------
# ----------------------------------------
# deleted by Andreas Warnke
# ----------------------------------------
# If RT is configured for external auth, let's get REMOTE_USER
# We intentionally don't test for REMOTE_USER to meet our policy
#elsif ($RT::WebExternalAuth){
#
# $user = $ENV{'REMOTE_USER'};
# $session{'CurrentUser'} = RT::CurrentUser->new();
# $session{'CurrentUser'}->Load($user);
# unless ($session{'CurrentUser'}->id() ) {
# delete $session{'CurrentUser'};
# $m->comp('/Elements/Login', %ARGS, Error=> 'You are not an
authorized user');
# $m->abort();
# }
#}
# ----------------------------------------
# If the user is loging in, let's authenticate
elsif (defined ($user) && defined ($pass)){
$session{'CurrentUser'} = RT::CurrentUser->new();
$session{'CurrentUser'}->Load($user);
unless ($session{'CurrentUser'}->id() ) {
delete $session{'CurrentUser'};
AttackEncountered();
$m->comp('/Elements/Login', %ARGS, Error=> 'Your username or
password is incorrect');
$m->abort();
};
unless ($session{'CurrentUser'}->IsPassword($pass)) {
delete $session{'CurrentUser'};
AttackEncountered();
$m->comp('/Elements/Login', Error => 'Your username or password
is incorrect', %ARGS);
$m->abort();
}
}
#If we've got credentials, lets serve the file up.
if ( (defined $session{'CurrentUser'}) and
( $session{'CurrentUser'}->Id) ) {
# If the user isn\'t privileged, they can only see SelfService
if ((! $session{'CurrentUser'}->Privileged) and
($m->base_comp->path !~ '^/+SelfService/') ) {
$m->comp('/SelfService/index.html');
$m->abort();
}
else {
$m->call_next;
}
}
#If we have no credentials
else {
AttackEncountered();
$m->comp('/Elements/Login', %ARGS);
$m->abort();
}
</%INIT>
<%ARGS>
$user => undef
$pass => undef
</%ARGS>
More information about the Rt-devel
mailing list