#34654: Post-normalization performed on the Username field leading to the bypass of the whitespace stripping ------------------------------+-------------------------------------------- Reporter: Sim4n6 | Owner: George Kussumoto Type: Bug | Status: assigned Component: contrib.auth | Version: dev Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 ------------------------------+-------------------------------------------- Comment (by George Kussumoto):
Here are some ideas to discuss: - To the main point of bypassing white space removal: while this is true for the `UsernameField`, most forms using this field also have another validation in the model level, such as `UnicodeUsernameValidator` and `EmailValidator`. These validators run on post-normalized values, so symbols like `BRAILLE PATTERN BLANK` or white space (regardless of position) will raise errors. - The `AuthenticationForm` might not invalidate such inputs, but to successfully exploit this, one should have bypassed the creation form first (I think). I'm not a security expert, but maybe there's an additional condition of using non-unique usernames. - The case for the password reset is already addressed in https://www.djangoproject.com/weblog/2019/dec/18/security-releases/ - When using custom user models things are different, the application code should include the appropriate validators. Depending on the implementation, the normalization steps too. - At first, I thought about adding `UnicodeUsernameValidator` to the `UsernameField`. It was promising, all tests passed. Then I realized it not only breaks compatibility, but we shouldn't make this assumption on the username since the validator is particular about what it accepts, compromising the flexibility to set `USERNAME_FIELD` in custom models. For example, `UnicodeUsernameValidator` is stricter than `EmailValidator` (at least at first glance). - Another possibility was to add the validator in the form definition instead of the form field (since it's expected some customization when using custom models). Possible candidates were `UserCreationForm` and `UserChangeForm` ([https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom- users-and-the-built-in-auth-forms custom-users-and-built-in-auth-forms doc]) since they are more tied to the default user model. But this is already accomplished by having the validator in the model. - As mentioned before in the comments, re-running `.strip()` after normalization or comparing string length doesn't seem to address the problem reported. So far, I don't have a conclusion, but I lean lightly on the side that no code changes are required. I wanted to share my thoughts and hear others. I don't have a security background so I might have overlooked/simplified things a bit. Please keep that in mind. -- Ticket URL: <https://code.djangoproject.com/ticket/34654#comment:13> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/010701909ea86f13-162896ca-a5b9-4a9f-bffe-b2bc2859c13b-000000%40eu-central-1.amazonses.com.