[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