jazzband / django-axes Goto Github PK
View Code? Open in Web Editor NEWKeep track of failed login attempts in Django-powered sites.
License: MIT License
Keep track of failed login attempts in Django-powered sites.
License: MIT License
can't get version number from axes/init.py
in https://github.com/codekoala/django-axes/blob/master/axes/__init__.py#L17 we should probably have django.core.exceptions.ImproperlyConfigured
instead of ImportError
The project needs a point update with the readme.md changes backported
Google Code, Bitbucket, GitHub...
This makes issue tracking (and maybe even code?) spread over many places which is bad and confusing. It seems GitHub is the most active copy so why not close the others? (After copying http://code.google.com/p/django-axes/issues/detail?id=5 here!)
The get_ip function (which uses HTTP_X_FORWARDED_FOR by default if BEHIND_REVERSE_PROXY) doesn't work in all cases. Sometimes, HTTP_X_FORWARDED_FOR returns a string containing multiple values (for example, '127.0.0.1, 192.30.252.129').
To fix this, I changed get_ip line 73 to:
return ip.split(', ')[-1]
A related article about this gotcha:
http://www.jamescrowley.co.uk/2007/06/19/gotcha-http-x-forwarded-for-returns-multiple-ip-addresses/
Anyone use axes with custom CBV login forms?
I try add axes my new project and see two problems.
I am running Django 1.6.10 and installed axes today. The code worked, I have version 1.3.9 of django-axes installed through pip, but I got a depreciation warning on some code:
../lib/python2.7/site-packages/axes/decorators.py:207: DeprecationWarning: The use of AUTH_PROFILE_MODULE to define user profiles has been deprecated.
profile = user.get_profile()
I have checked the documentation and here is the note about fixing up the respective code.
http://django.readthedocs.org/en/latest/topics/auth/customizing.html#auth-custom-user
Note this is a different warning than the one issued for this issue: #55.
I have checked all the open and closed issues and pull requests this Warning does not seem to have been captured.
Add an option to whitelist IP addresses
Since IPv6 address are often longer than IPv4 address, the database storage for the IP address gets truncated, causing failures when a user tries to log in.
I believe that one way to solve this is to use a GenericIPAddressField
, which supports longer IP addresses, like IPv6.
This would, unfortunately, mean a database change, and I notice that Axes doesn't have any migration set up yet (such as South). I'm not sure what the migration strategy for this would be.
File "d:\dev\python\lib\site-packages\django_axes-1.3.8-py3.4.egg\axes\management\commands\axes_list_attempts.py", line 12
print "%s %s %s" % (at.ip_address, at.username, at.failures)
^
SyntaxError: invalid syntax
I'm using django 1.7 & Python 3.4.1
Hi, I use axes to watch the logins on my site, but in my database (table axes_accessattempt) there is always the wrong time. I life in germany and when I signin into my website on 8:25 in the field attempt_time is the value 7:25. I looked around and saw that you use the function "now" from django.utils.timezone. I think this is wrong. You should use timezone.localtime(timezone.now()) to get the right time.
Add a configuration option to do as many large sites do- force the user to pass a captcha when they are locked out, instead of locking the user out from the site entirely
django-axes logs POST data of login requests in full. This allows a potentialy large amount of data to be logged in the database.
How to reproduce:
dd if=/dev/urandom of=bigfile bs=1M count=1
curl -F 'file=<bigfile' http://localhost:8000/admin/ # See note.
The model instance in AccessAttempts now contains the full content of the file. This can be misused to fill the disk space, or slow down the browser when viewing the model instance page (esp. Firefox does not handle it very well).
django-axes should only log a limited amount of POST data, e.g. 1 kB.
Note: For this to work, CSRF needs to be disabled, e.g. with:
example/settings.py:
MIDDLEWARE_CLASSES = (
...
'middleware.DisableCSRF',
)
example/middleware.py:
class DisableCSRF(object):
def process_request(self, request):
setattr(request, '_dont_enforce_csrf_checks', True)
Hi,
The tests seem to fail. I really can't explain why, but it's an off by one error.
Weirdly enough, it's off by +1 on Django 1.2, and off by -1 on Django 1.3.
I've made a fork to fix this so my tests stop failing:
https://github.com/vanschelven/django-axes
I've also added two sample project directories so you can test in isolation for both Django 1.2 and Django 1.3
Any idea as to how this is possible?
Klaas
Hi,
We're using django-axes in a one-page application where login is performed as an AJAX request. We've run into two deficiencies:
There is no good way to return a JSON response when the user is locked. We have used the template response to return JSON content, but it returns with the wrong type.
There is no way at all to extract the username from the response -- Axes only looks for it in form fields, so the blocking uses only the IP address (which is bad, many of our users are in groups behind NAT).
I've noticed that between 1.3.9 and 1.4.0, axes.decorators.get_user_attempts
is not working as expected. After lots of failed logins, it's not returning any attempt and not locking the account.
I think I've found where is the problem:
My settings:
# django-axes
AXES_LOGIN_FAILURE_LIMIT = 2
AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP = True
AXES_LOCKOUT_TEMPLATE = 'layouts/marketingsite/account_locked.html'
If I change the trusted=True
condition, everything works as usual:
# axes/decorators.py
attempts = AccessAttempt.objects.filter(
ip_address=ip, username=username, trusted=False
)
Any ideas?
I'm working with both django-two-factor-auth and django-axes and I'm curious if there is a better way to implement the logic found in watch_login, then inspecting the response object
if request.method == 'POST':
# see if the login was successful
login_unsuccessful = (
response and
not response.has_header('location') and
response.status_code != 302
)
The problem that occurs with django-two-factor-auth is that the response object for the verification code entry page looks no different then a failed logic attempt. It is not a redirect, so the response code is 200, and it also does not have a 'location' header. I tried fixing this on a fork, but was not successful yet.
Any advice?
Test and ship a version supporting django 1.7
I set AXES_LOGIN_FAILURE_LIMIT
to 3, and was confused when it always allowed 4 attempts before locking it down.
Diving into the code, it turns out failures starts on 0, and is incremented after the failure, which makes sense, except that the code is checking if failures is GREATER than AXES_LOGIN_FAILURE_LIMIT.
I'm using django 1.6 and receiving the following error when attempting to access the login page after installing axes:
NoReverseMatch at /accounts/login/
Reverse for 'axes.decorators.decorated_login' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
I'm able to access the admin panel without a problem and axes logs in the attempt accordingly.
My login.html is the following which is causing the error:
<form method="post" action="{% url 'django.contrib.auth.views.login' %}" class="form-signin" role="form">
Nothing crazy going on here, here is the applicable urls.py:
url(r'^accounts/login/$', auth_views.login),
Any thoughts on what is causing the issue?
The library doesn't send the lockout signal. Tried both with decorator and middleware.
Debugging check_request, it does not pass through it when locking out the user, maybe the control
if is_already_locked(request):
in watch_login prevents the signal sending by returning directly?
Or am I missing something else?
django-axes requires Django 1.0 or later.
With 5cf1f2d it requires settings.USE_TZ introduced in Django 1.4.
Add an option to email admins if an IP is being continually banned.
I'm guessing that django 1.4 changed how this was handled, but using FailedLoginMiddleware
causes the login decorator to be called twice, adding two failures to the access entry instead of one.
Using only FailedAuthLoginMiddleware
solves the problem, and it still works for admin.
The behavior for tracking a user's log out time needs to be updated to account for multiple sessions by the same user.
Currently, when a user logs out, the most recent AccessLog
row has its logout_time
set to the current time. (See https://github.com/django-security/django-axes/blob/1.3.6/axes/signals.py#L26-L33)
However, if there are multiple sessions open, this simple logic may set the incorrect record.
A session_key
field could be added to AccessLog
to allow tracking of the login session in watch_login
. Then the logout signal handler should look up the correct AccessLog
row using session_key
.
Add an option to blacklist IP addresses
While installing django-axes its __init__.py
file tries to import Django's settings. However, these may not be available yet in many scenarios. Example: doing a
pip install -r requirements.txt
may install the lines in that file in any order.
See also my comment on:
9a6f96c
Fixing this should be a matter of minutes
Shouldnt there be a 'username' field in the Django admin, so the admin can identify per user logs?
A SyntaxError preventing Python 3 usage (#104) has been fixed for a while on master, but that little annoyance remains on PyPI. Any chance of getting a new release on the package index for easy-fun-time?
https://github.com/django-security/django-axes/blob/master/axes/decorators.py#L71 is pretty noisy while not being very informative, I'd say.
I'd suggest to make this
a) a one-time log message or
b) log it through the configurable named logger axes.watch_login to ease filtering for these messages.
What do you think?
Hello, thank you for your awesome project. I needed such Brute Force defence and I found your project. It is great and fit exactly my need.
Before start the report, talk to you my environment. I installed your project via pip, the version is 1.3.9, and I read your README from the github main page of the project.
I think there is a wrong description therefore report it. My English is poor, so please check I got it right.
Your document says that :
AXES_USE_USER_AGENT: If True, lock out / log based on an IP address AND a user agent. This means requests from different user agents but from the same IP are treated differently. Default: False
I think this description says next situation will be shown:
Set AXES_LOGIN_FAILURE_LIMIT = 3
Set AXES_USE_USER_AGENT = True
Try failure login with username 'A' two times.
Next Try failure login with username 'B' two times.
The server not block the ip or username because they are attempt less than AXES_LOGIN_FAILURE_LIMIT.
But when I tried, the ip is blocked and the block is not considered the username.
After that, I changed the value of AXES_USE_USER_AGENT to False and I can found the upper situation is made. It looks like in opposite operation to the documentation.
Would you check this please?
Hi,
There is this comment in the reset code:
# no need to reset trusted records. If they fail, they go to untrusted
And you then add 'trusted': false to params.
However I have access attempts in the db that are marked as trusted, are over the failure limit, and therefore there are users getting locked out permanently due to the is_already_locked() short circuit in the decorated_login function.
Any idea what might be going wrong here?
Thanks in advance,
Ben
Not sure exactly what is going on here but I am installing using a virtual environment and the install is failing. I suspect it is trying to load up something from django during the install and since there is no actual project it is failing.
Here is the console output:
christian@PC006:~/documents/projects/ratherhave$ /home/christian/documents/projects/ratherhave/venv/bin/pip install django-axes
Downloading/unpacking django-axes
Running setup.py egg_info for package django-axes
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/christian/documents/projects/ratherhave/venv/build/django-axes/setup.py", line 6, in <module>
version = __import__('axes').get_version()
File "axes/__init__.py", line 15, in <module>
if settings.LOGGING:
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/christian/documents/projects/ratherhave/venv/build/django-axes/setup.py", line 6, in <module>
version = __import__('axes').get_version()
File "axes/__init__.py", line 15, in <module>
if settings.LOGGING:
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
----------------------------------------
Command python setup.py egg_info failed with error code 1 in /home/christian/documents/projects/ratherhave/venv/build/django-axes
Storing complete log in /home/christian/.pip/pip.log
christian@PC006:~/documents/projects/ratherhave$
And here is the pip.log file:
------------------------------------------------------------
/home/christian/documents/projects/ratherhave/venv/bin/pip run on Sat Jun 1 18:16:37 2013
Downloading/unpacking django-axes
Running setup.py egg_info for package django-axes
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/christian/documents/projects/ratherhave/venv/build/django-axes/setup.py", line 6, in <module>
version = __import__('axes').get_version()
File "axes/__init__.py", line 15, in <module>
if settings.LOGGING:
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/christian/documents/projects/ratherhave/venv/build/django-axes/setup.py", line 6, in <module>
version = __import__('axes').get_version()
File "axes/__init__.py", line 15, in <module>
if settings.LOGGING:
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
self._setup(name)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
----------------------------------------
Command python setup.py egg_info failed with error code 1 in /home/christian/documents/projects/ratherhave/venv/build/django-axes
Exception information:
Traceback (most recent call last):
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg/pip/basecommand.py", line 104, in main
status = self.run(options, args)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg/pip/commands/install.py", line 245, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg/pip/req.py", line 1009, in prepare_files
req_to_install.run_egg_info()
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg/pip/req.py", line 225, in run_egg_info
command_desc='python setup.py egg_info')
File "/home/christian/documents/projects/ratherhave/venv/local/lib/python2.7/site-packages/pip-1.1-py2.7.egg/pip/__init__.py", line 256, in call_subprocess
% (command_desc, proc.returncode, cwd))
InstallationError: Command python setup.py egg_info failed with error code 1 in /home/christian/documents/projects/ratherhave/venv/build/django-axes
Thanks!
specifically, make sure it's compatible with Django 1.2 and Django 1.3
Hard to believe but this user agent exist:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; BTRS123646; SIMBAR={948FDCDC-90AF-11E1-BE08-005056C00008}; GTB7.4; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; .NET CLR 1.1.4322)
Asking how long it is:
>>> len('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; BTRS123646; SIMBAR={948FDCDC-90AF-11E1-BE08-005056C00008}; GTB7.4; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; .NET CLR 1.1.4322)')
272
So it will be better to increase the max_length to avoid the issue
The middleware will redecorate the auth_views.login
function on every single request. That is why you need the if func.__name__ == 'decorated_login':
inside the watch_login. You should rather do this check inside the middleware, or better, add the watch_login wrapper somewhere else. I don't see a reason it needs to be in middleware at all?
In django >1.5
in decorators.py, line 135
get_profile method is deprecated, throws an error if you have custom user model
Hello,
From time to time I get the following error:
function host(character) does not exist
LINE 1: ...HERE ("axes_accessattempt"."username" IS NULL AND HOST("axes...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
And emptying the 2 axes tables does not solve it. I digged into Django code and the SQL query seems fine so this might be a Postgres bug. But it is very annoying. The only way it works again for me is to delete the 2 axes tables and then recreate them. Anybody else having the same issue?
PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
Thanks,
Eras
Add option to make bans tied to user rather than IP
When running on heroku, axes is useless because of heroku's internal ip reported on REMOTE_ADDR. Django easy timezones includes a nice block for getting the real ip -
https://github.com/Miserlou/django-easy-timezones/blob/master/easy_timezones/utils.py
Will add a pull with the changes.
When spawning failed login signals, the system does not pass to them any request data.
This is uncomfortable for whoever may want to track failed logins IP for monitoring purposes and attack prevenction.
We're testing django-axes 1.5.0 from PyPi in a project upgraded to django 1.8.4, but when we try to reset an IP address in a management command we get this error:
$ ./manage.py axes_reset 123.123.123.123
usage: manage.py axes_reset [-h] [--version] [-v {0,1,2,3}]
[--settings SETTINGS] [--pythonpath PYTHONPATH]
[--traceback] [--no-color]
manage.py axes_reset: error: unrecognized arguments: 123.123.123.123
I fairly sure this is related to this: https://docs.djangoproject.com/en/1.8/releases/1.8/#management-commands-that-only-accept-positional-arguments
Maybe this is because the args command variable is an empty string? https://github.com/django-pci/django-axes/blob/master/axes/management/commands/axes_reset.py#L8
30 nov 2013, 14:54 (None) Mozilla/5.0 test /my/login/ 1
30 nov 2013, 14:54 XXX.XX.XX.XXX Mozilla/5.0 (None) /my/login/ 1
I keep getting two login attempts, one with the IP adress, but no username, one visa versa..
My django app is on nginx with gunicorn as proxy. I have added the paramters to retrieve the real ip adress, but I reckon this has to do with another param or axes setting I have overlooked?
My setup
nginx:
proxy_pass_request_headers on;
proxy_pass_request_body on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
django settings:
AXES_BEHIND_REVERSE_PROXY = True
I can't claim to understand all the ins and outs of the logging module as used by Django 1.3+, but in my current environment (django 1.4.3, celery 3.0.15, django-celery 3.0.11), axes.log -- sometimes -- gets verbose logging for lots of stuff it doesn't seem like it should, modules in my project that don't even have a logging configuration in my settings.py.
Is the call to logging.basicConfig in init.py conflicting with the project logging configuration? Could there be a clean way to append to LOGGING, if present?
Anyone else having problems with this?
See also
http://stackoverflow.com/questions/6367927/django-python-logging
Performance improvement: Use cache to store failed logins, SQL queries are slow. Django-axes should use Django's cache framework for storing failed logins.
For example, you guys could store keys with the format axes-<hash>
where the hash is md5(ip+ua)
. The data for that key should be the number of failed logins sent by that ip+ua and the timeout for the key is the AXES_COOLOFF_TIME
At the moment there is a global login failure limit:
AXES_LOGIN_FAILURE_LIMIT
it would be better if it were per user so that a user.
Eg. everywhere it's used:
getattr(user_obj, "login_failure_limit", settings.AXES_LOGIN_FAILURE_LIMIT)
the particular use case we have is:
class MyUser(AbstractUser):
...
@property
def login_failure_limit(self):
if not self._login_failure_limit:
self._login_failure_limit = self.site_profiles_set.order_by('-login_failure_limit').values_list('login_failure_limit', Flat=True))[0]
return self._login_failure_limit
Quoting the documentation...
manage.py reset will reset all lockouts and access records.
This is technically correct, but it will reset a lot more!
manage.py reset ip will clear lockout/records for ip
No, it will say that you have no app named as the ip address (or if you did, reset it).
Does django-axes work with the django bundled admin application out of the box? If not, what steps are necessary to enable that?
Could you add a section about that to the documentation? Many people are using the admin app so it should definitely be protected by axes too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.