Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: AXES_PASSWORD_FORM_FIELD fails to redact password field from AccessAttempt.post_data if a custom login form prefix is used. #1139

Open
michaeljtbrooks opened this issue Nov 22, 2023 · 1 comment

Comments

@michaeljtbrooks
Copy link

Describe the bug
If a custom login form implementation in Django uses a form prefix and a custom password field name, then AXES_PASSWORD_FORM_FIELD will fail to redact that field from the request.POST and request.GET if AXES_PASSWORD_FORM_FIELD is set to just the form's password fieldname without the prefix as the variable's name implies.

The documentation implies that no prefix is necessary: "The name of the form or credentials field that contains your users password."

Confusingly settings.AXES_USERNAME_FORM_FIELD works fine without the prefix because when it is pulled from credentials (see axes.helpers.get_client_username), this would be the form's username field name without the form's prefix. There is then the fallback method to pull from request.POST which would need the prefix.

Thus, if a developer uses a custom login form with a form prefix, and sets AXES_USERNAME_FORM_FIELD to the field name without the prefix, things will work fine and the username will be found. But if they also set AXES_PASSWORD_FORM_FIELD to the form's password field name without the form prefix, then Axes will fail to redact the password.

To Reproduce
Steps to reproduce the behavior:

  1. Create a custom login form view, where the authentication form has a username field called "uname" and a password field called "pword" and is initialised with a prefix e.g. "login"
  2. Set settings.AXES_USERNAME_FORM_FIELD to "uname"
  3. Set settings.AXES_PASSWORD_FORM_FIELD to "pword"
  4. Attempt to login, deliberately getting the login credentials wrong
  5. Inspect the database, check the last entry for AccessAttempt, you'll see "login-pword" appear in the post_data

Expected behavior
The request.POST and request.GET cleansing routine (AxesDatabaseHandler.user_login_failed -> get_query_str() -> cleanse_parameters()) should be able to strip keys matching (?:.*-)?{AXES_PASSWORD_FORM_FIELD} from the querydict.

We won't know the form prefix at the level of inspecting the request.POST querydict, thus it'll have to be a wildcard match. If you want to be more specific, you could introduce a new setting: AXES_LOGIN_FORM_PREFIX, defaulting to "", and thus strip keys with and without this prefix.

A less robust fix would be to update the documentation to explain that any custom form prefix is necessary for AXES_PASSWORD_FORM_FIELD, but that would be a bit lame IMO.

Your environment
python version: 3.9
django version: 3.2
django-axes version: 6.1.1
Operating system: Linux Mint 21.2

@aleksihakli
Copy link
Member

Thanks for reporting. Would someone like to open a PR for the fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants