Re: [Django] #36901: Centralize mitigations against timing attacks targeting user enumeration

7 views
Skip to first unread message

Django

unread,
Feb 5, 2026, 1:33:29 PMFeb 5
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Sarah
Type: | Boyce
Cleanup/optimization | 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
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* stage: Unreviewed => Accepted

Comment:

Thank you!
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Mar 23, 2026, 7:31:07 AMMar 23
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Sarah
Type: | Boyce
Cleanup/optimization | 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 Afenomamy):

Hello, this is Aina (Team Saturn) from Djangonaut Space. I will be
looking at this ticket
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:4>

Django

unread,
Mar 23, 2026, 7:31:58 AMMar 23
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
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
-------------------------------------+-------------------------------------
Changes (by Afenomamy):

* owner: Sarah Boyce => Afenomamy

--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:5>

Django

unread,
Mar 30, 2026, 9:58:56 AM (11 days ago) Mar 30
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
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 Afenomamy):

So my plan is :
1 - Create two utility functions called **get_user_with_mitigation** and
**aget_user_with_mitigation** inside django.contrib.auth.__init__.py.
2 - Update **django.contrib.auth.handlers.modwsgi.check_password** to use
''get_user_with_mitigation''
3 - Refactor authenticate and aauthenticate in
**django.contrib.auth.backends.py** to use ''get_user_with_mitigation and
aget_user_with_mitigation'' .


NB :
- For **Attribute Safety**: getattr(user, 'is_active', True) will be
used to ensure compatibility with custom user models that do not define
an is_active field. This will resolve the reported AttributeError.
- For **Performance:** make_password will be called directly for
the dummy hashing. This avoids the overhead of instantiating a UserModel
instance simply to call set_password().
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:6>

Django

unread,
Mar 31, 2026, 6:22:57 AM (11 days ago) Mar 31
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Afenomamy):

* has_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:7>

Django

unread,
Mar 31, 2026, 7:33:10 AM (10 days ago) Mar 31
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Tim Schilling):

@Jacob Walls, can you clarify what you mean by "reduce the number of calls
to set_password("")" please? Is it to remove the calls because that is a
hack and we should have a clearer method or to reduce the amount of times
the hashing mechanism is run?
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:8>

Django

unread,
Mar 31, 2026, 8:40:37 AM (10 days ago) Mar 31
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls):

Certainly. The Security Team was concerned that the reason we missed CVE
2025-13473 -- the bug where Django wasn't running the password hasher once
for inactive users in the modwsgi handler -- was because of a DRY (Don't
Repeat Yourself) problem. Since there was no central utility encapsulating
"get active user and check password, or else run password hasher once".

That's what I meant here:

> A refactor in exposing this functionality in a central place that the
mod_wsgi auth handler could just call is worth exploring.

Could we refactor both ModelBackend and modwsgi handler (and possibly any
other places) to just call one utility encapsulating the security concept,
in case we need tweaks to it later.
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:9>

Django

unread,
Apr 1, 2026, 8:03:47 AM (9 days ago) Apr 1
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls):

Ah, I think I see what you may have been asking. Let's say there are four
calls to `make_password("")`. I'm suggesting that there should be four
calls to a helper that manages that instead, since calling
`make_password("")` in the right conditions is tricky to get right.
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:10>

Django

unread,
Apr 1, 2026, 9:59:27 AM (9 days ago) Apr 1
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Tim Schilling):

That is more of what I was looking for, but your earlier answer was
helpful too. Thank you.
--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:11>

Django

unread,
Apr 1, 2026, 5:17:26 PM (9 days ago) Apr 1
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:12>

Django

unread,
10:22 AM (9 hours ago) 10:22 AM
to django-...@googlegroups.com
#36901: Centralize mitigations against timing attacks targeting user enumeration
-------------------------------------+-------------------------------------
Reporter: Jacob Walls | Owner: Afenomamy
Type: | Status: assigned
Cleanup/optimization |
Component: contrib.auth | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Schilling):

* needs_docs: 0 => 1
* needs_tests: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36901#comment:13>
Reply all
Reply to author
Forward
0 new messages