Skip to content

Commit

Permalink
Authentication configuration errors are reported to the KB only after…
Browse files Browse the repository at this point in the history
… 3 failed logins
  • Loading branch information
andresriancho committed Nov 13, 2019
1 parent 0631749 commit c237bc3
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 31 deletions.
28 changes: 28 additions & 0 deletions w3af/core/controllers/plugins/auth_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,17 @@ class AuthPlugin(Plugin):
:author: Dmitriy V. Simonov ( dsimonov@yandex-team.com )
"""

MAX_FAILED_LOGIN_COUNT = 3

def __init__(self):
Plugin.__init__(self)

self._uri_opener = None
self._debugging_id = None
self._http_response_ids = []
self._log_messages = []
self._attempt_login = True
self._failed_login_count = 0

def login(self):
"""
Expand Down Expand Up @@ -113,6 +117,30 @@ def _get_main_authentication_url(self):
"""
raise NotImplementedError

def _handle_authentication_failure(self):
self._failed_login_count += 1

if self._failed_login_count == self.MAX_FAILED_LOGIN_COUNT:
msg = ('Authentication plugin failed %s consecutive times.'
' Disabling authentication plugin.')
args = (self._failed_login_count,)
self._log_debug(msg % args)

self._log_info_to_kb()

self._attempt_login = False

def end(self):
if self._failed_login_count:
msg = 'Authentication plugin failed %s times during the last minutes of the scan.'
args = (self._failed_login_count,)
self._log_debug(msg % args)

self._log_info_to_kb()

def _handle_authentication_success(self):
self._failed_login_count = 0

def _log_info_to_kb(self):
"""
This method creates an Info object containing information about failed
Expand Down
23 changes: 14 additions & 9 deletions w3af/plugins/auth/autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ def __init__(self):
self.check_url = URL('http://host.tld/check')
self.check_string = ''

# Internal attributes
self._attempt_login = True

def login(self):
"""
Login to the application:
Expand Down Expand Up @@ -80,6 +77,7 @@ def login(self):
form = self._get_login_form()

if not form:
self._handle_authentication_failure()
return False

#
Expand All @@ -88,22 +86,29 @@ def login(self):
form_submitted = self._submit_form(form)

if not form_submitted:
self._log_info_to_kb()
self._handle_authentication_failure()
return False

if not self.has_active_session():
self._log_info_to_kb()
return False
#
# Check if we're logged in
#
if self.has_active_session():
self._handle_authentication_success()
return True

self._log_debug('Login success for user %s' % self.username)
return True
self._handle_authentication_failure()
return False

def logout(self):
"""
User logout
"""
return None

def _handle_authentication_success(self):
super(autocomplete, self)._handle_authentication_success()
self._log_debug('Login success for %s' % self.username)

def _submit_form(self, form_params):
"""
Complete the username and password in the form fields and submit it
Expand Down
18 changes: 9 additions & 9 deletions w3af/plugins/auth/detailed.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ def __init__(self):
self.follow_redirects = False
self.url_encode_params = True

# Internal attributes
self._show_login_error = True
self._attempt_login = True

def login(self):
"""
Login to the application
Expand Down Expand Up @@ -100,19 +96,23 @@ def login(self):
#
# Check if we're logged in
#
if not self.has_active_session():
self._log_info_to_kb()
return False
if self.has_active_session():
self._handle_authentication_success()
return True

om.out.debug('Login success for %s' % self.username)
return True
self._handle_authentication_failure()
return False

def logout(self):
"""
User logout
"""
return None

def _handle_authentication_success(self):
super(detailed, self)._handle_authentication_success()
self._log_debug('Login success for %s' % self.username)

def _get_data_from_format(self):
"""
:return: A string with all the information to send to the login URL.
Expand Down
17 changes: 9 additions & 8 deletions w3af/plugins/auth/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ def __init__(self):
self.check_url = 'http://host.tld/'
self.check_string = ''

# Internal attributes
self._attempt_login = True

def login(self):
"""
Login to the application.
Expand Down Expand Up @@ -93,19 +90,23 @@ def login(self):
#
# Check if we're logged in
#
if not self.has_active_session():
self._log_info_to_kb()
return False
if self.has_active_session():
self._handle_authentication_success()
return True

om.out.debug('Login success for %s' % self.username)
return True
self._handle_authentication_failure()
return False

def logout(self):
"""
User logout
"""
return None

def _handle_authentication_success(self):
super(generic, self)._handle_authentication_success()
self._log_debug('Login success for %s' % self.username)

def get_options(self):
"""
:return: A list of option objects for this plugin.
Expand Down
3 changes: 2 additions & 1 deletion w3af/plugins/tests/auth/test_autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ def test_handle_invalid_credentials(self):
'Login form with action http://w3af.org/login_post.py found in HTTP response with ID 21\n'
'Login form sent to http://w3af.org/login_post.py in HTTP request ID 22\n'
'Checking if session for user user@mail.com is active\n'
'User "user@mail.com" is NOT logged into the application, the `check_string` was not found in the HTTP response with ID 23.'
'User "user@mail.com" is NOT logged into the application, the `check_string` was not found in the HTTP response with ID 23.\n'
'Authentication plugin failed 1 times during the last minutes of the scan.'
)

self.assertEqual(info.get_name(), 'Authentication failure')
Expand Down
8 changes: 4 additions & 4 deletions w3af/plugins/tests/auth/test_detailed.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ def test_failed_login_invalid_password(self):
info = infos[0]

expected_desc = (
'The authentication plugin failed to get a valid application session using'
' the user-provided configuration settings.\n'
'The authentication plugin failed to get a valid application session using the user-provided configuration settings.\n'
'\n'
'The plugin generated the following log messages:\n'
'\n'
'Logging into the application with user: user@mail.com\n'
'User "user@mail.com" is NOT logged into the application, the'
' `check_string` was not found in the HTTP response with ID 24.'
'Checking if session for user user@mail.com is active\n'
'User "user@mail.com" is NOT logged into the application, the `check_string` was not found in the HTTP response with ID 24.\n'
'Authentication plugin failed 1 times during the last minutes of the scan.'
)

self.assertEqual(info.get_name(), 'Authentication failure')
Expand Down

0 comments on commit c237bc3

Please sign in to comment.