## https://sploitus.com/exploit?id=0D16558B-1987-55E8-8B0C-78FA3C064D7C
#CVE-2026-51788
Summary
cleverange_auth versions up to and including 0.1.10 contain an authentication backend flaw that allows a remote, unauthenticated attacker to trigger expensive password-hashing operations for usernames or email addresses that do not exist in the system. Repeated requests can be used to exhaust CPU resources on the application server, resulting in a denial of service.
CVE IDCVE-2026-51788Affected Componentaccounts/backends.py โ EmailOrUsernameBackend.authenticateAffected Versionscleverange_auth <= 0.1.10Vulnerability ClassCWE-400 (Uncontrolled Resource Consumption), CWE-208 (Observable Timing Discrepancy)CVSS 3.1 (estimated)~5.3 (Medium) โ AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:LReported byAykhanStatusReserved (public disclosure pending)
Technical Details
The custom authentication backend is intended to mitigate username-enumeration timing attacks by performing a password hash even when the supplied identifier does not correspond to an existing user:
pythonclass EmailOrUsernameBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username__iexact=username) | Q(email__iexact=username))
except User.DoesNotExist:
User().set_password(password)
return
...
This pattern is a known mitigation idiom (Django itself does something similar internally), but the implementation here has two problems:
No bound on hashing cost per request. set_password() runs the full configured password hasher (PBKDF2/Argon2/bcrypt, depending on Django settings) against attacker-controlled input on every failed-lookup login attempt. There is no rate limiting, request size cap, or backoff at this layer. An attacker can send a high volume of login requests with non-existent usernames โ optionally with long password strings, since hashing cost scales with input in some hasher configurations โ driving sustained CPU load on the authentication path.
The timing mitigation is incomplete. Because the hash is computed synchronously only in the DoesNotExist branch, and a second, separate hash comparison (user.check_password(password)) occurs in the success path for valid usernames, the actual time-to-response still differs measurably between "user exists" and "user does not exist" cases depending on server load โ so the original enumeration-timing concern isn't fully closed either.
Impact
Availability: A remote unauthenticated attacker can degrade or exhaust CPU capacity on instances using this backend by flooding the login endpoint with non-existent-user credentials, effectively a denial of service against the authentication path (and potentially the whole application, if login runs on a shared worker pool).
Confidentiality: Secondary/lower-severity โ residual timing variance may still provide a weak signal for username enumeration under some deployment conditions.
No data disclosure or authentication bypass is provided by this issue on its own.
Proof of Concept
Reproduction requires only standard, unauthenticated access to the login endpoint:
Deploy a Django project using cleverange_auth with EmailOrUsernameBackend configured in AUTHENTICATION_BACKENDS.
Send repeated POST requests to the login view with usernames guaranteed not to exist in the User table, using the default authenticate flow.
Observe CPU utilization on the process handling authentication as request volume increases โ hashing work is performed identically to a real login attempt, with no throttling.
(No weaponized script accompanies this writeup; the above is sufficient for a defender or maintainer to reproduce and confirm the resource-consumption behavior locally.)
Remediation
Apply rate limiting / request throttling (e.g., Django Axes, django-ratelimit) on the authentication endpoint, independent of whether the username exists.
Consider using a constant, cheap dummy-hash comparison (fixed cost, not tied to input length) instead of a full set_password() call for the non-existent-user branch, or cache/precompute a static dummy hash rather than generating one per request.
Cap input length for username/password fields before they reach the hasher.
No patched version is currently available upstream; users of cleverange_auth <= 0.1.10 should mitigate at the infrastructure/WAF layer (rate limiting) until a fix is released.
Disclosure Timeline
2026-04-27: CVE request submitted to the CVE Assignment Team.
2026-07-08: CVE-2026-51788 confirmed reserved; advisory drafted.
Credit
Discovered and reported by Aykhan.
References
CVE-2026-51788 (MITRE): https://vulners.com/cve/CVE-2026-51788