Cloudanix VulnDB

CVE-2024-45231

None

CVSS

—

EPSS

0.8%

Published

Oct 8, 2024

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A flaw in some Django password reset pages can let outsiders figure out which email addresses have accounts if the site’s email sending is failing.

Chainable
Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Moderate
Impact
Data Exposure
Component
Web Framework
Class
Information Disclosure
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

CVE-2024-45231 is an information disclosure flaw in Django’s django.contrib.auth.forms.PasswordResetForm as shipped in Django 5.1.1, 5.0.9, and 4.2.16. In applications that use this form in a password-reset view, remote unauthenticated users may be able to distinguish whether a submitted email address belongs to an existing user when outbound email delivery consistently fails. The flaw does not directly expose passwords or allow account takeover by itself, but it can disclose valid account identifiers that can be reused for phishing, credential stuffing, social engineering, or targeted password attacks.

Why it matters to the business

Organizations running affected Django versions may unintentionally reveal which email addresses have accounts in their applications during password reset attempts. This can increase the risk of targeted phishing, credential stuffing, privacy complaints, and regulatory exposure where account membership is sensitive. The EPSS score is low and there is no CISA KEV listing or known ransomware association, so this is generally a lower-urgency vulnerability than direct code execution or authentication bypass issues; however, internet-facing applications with sensitive user populations should still prioritize remediation because enumeration weaknesses are easy to automate at scale.

How an attack unfolds

An attacker identifies an application using Django’s built-in password reset flow or a view based on django.contrib.auth.forms.PasswordResetForm. The attacker submits password reset requests for a list of candidate email addresses. Under normal secure behavior, the application should respond indistinguishably whether or not the account exists. In the vulnerable condition, when email sending is consistently failing, the password reset handling can produce observably different outcomes depending on whether the submitted address matches an existing user. The attacker compares response status codes, response bodies, redirects, timing, or error behavior to infer valid user email addresses. The resulting list can then be used for follow-on attacks such as phishing, password spraying, credential stuffing, or privacy-invasive profiling.

How to fix it

Upgrade Django to a version containing the upstream fix for PasswordResetForm. For source-based deployments of django/django, update to a revision containing commit 6f9fea33137fee6416ff43b775aa9567440a23d3 or later. Ensure packaged Django dependencies are upgraded to the corresponding vendor release that includes this fix. As defense in depth, make password reset responses uniform regardless of whether the email exists or whether email delivery succeeds, avoid exposing backend mail errors to users, log mail delivery failures server-side only, and apply rate limiting, CAPTCHA or abuse controls, and monitoring to password reset endpoints.

How to confirm the fix worked

Confirm the deployed Django version or source revision includes the fix, specifically commit 6f9fea33137fee6416ff43b775aa9567440a23d3 or a later patched release. Review dependency lockfiles, container images, and runtime package versions to ensure affected versions 5.1.1, 5.0.9, and 4.2.16 are not in use. Test the password reset flow by submitting requests for both existing and non-existing email addresses while simulating email delivery failure; responses should be indistinguishable in status code, body content, redirects, and user-visible error handling. Verify that email backend exceptions are not exposed to unauthenticated users and that password reset attempts are rate-limited and logged.

Typical attack path

  1. Locate an internet-facing Django application with a password reset endpoint.
  2. Send password reset requests using known or guessed email addresses.
  3. Observe response differences when outbound email delivery is failing, such as errors, redirects, status codes, messages, or timing changes.
  4. Classify email addresses as likely valid or invalid based on the observed behavior.
  5. Use enumerated valid addresses for targeted phishing, credential stuffing, password spraying, or social engineering.

How to detect it

Review web access logs, application logs, authentication logs, and mail delivery/error logs for evidence of password reset enumeration. Focus on periods when outbound email sending was failing or intermittently unavailable, because the vulnerability depends on consistent email delivery failure producing observable differences. Look for repeated unauthenticated POST requests to password reset endpoints, high numbers of distinct submitted email addresses, sequential or dictionary-style email attempts, unusual spikes in reset requests from a single IP address or user agent, and correlation with SMTP/backend mail exceptions. Compare application responses for reset requests during mail failures to determine whether different status codes, redirects, or error messages were returned for valid versus invalid addresses. Also monitor downstream activity against potentially enumerated users, such as increased failed logins, password spraying patterns, phishing reports, or MFA challenge spikes.

  • POST /password_reset/
  • POST /accounts/password_reset/
  • POST /accounts/password/reset/
  • POST /registration/password_reset/
  • PasswordResetForm
  • SMTPException
  • smtplib.SMTPException
  • SMTPConnectError
  • SMTPServerDisconnected
  • SMTPAuthenticationError
  • ConnectionRefusedError
  • [Errno 111] Connection refused
  • [Errno 110] Connection timed out
  • Failed to send password reset email
  • password reset

What your security team should do

  • Inventory applications using Django password reset flows, especially those exposing password reset endpoints to the internet.
  • Upgrade affected Django deployments to a patched version or source revision containing commit 6f9fea33137fee6416ff43b775aa9567440a23d3 or later.
  • Prioritize applications where account membership is sensitive, such as healthcare, financial, employee, government, or high-profile consumer services.
  • Review password reset views for uniform responses and ensure backend email delivery failures are not reflected in user-visible behavior.
  • Add or tune rate limiting, bot detection, and alerting for high-volume password reset attempts from the same IP, ASN, user agent, or email pattern.
  • Search historical logs for password reset enumeration patterns, especially bursts involving many distinct email addresses and concurrent mail delivery failures.
  • Monitor for follow-on activity against enumerated accounts, including password spraying, credential stuffing, phishing reports, and suspicious login failures.

The record

An issue was discovered in Django v5.1.1, v5.0.9, and v4.2.16. The django.contrib.auth.forms.PasswordResetForm class, when used in a view implementing password reset flows, allows remote attackers to enumerate user e-mail addresses by sending password reset requests and observing the outcome (only when e-mail sending is consistently failing).

Affected packages

Ecosystem Package Introduced Fixed
PyPI django 0 4.2.16
PyPI django 5.0 5.0.9
PyPI django 5.1 5.1.1
Bitnami django 4.2.0 4.2.16
Debian:11 python-django 0 No fix
Debian:12 python-django 0 No fix
Debian:13 python-django 0 3:4.2.16-1
Debian:14 python-django 0 3:4.2.16-1
Mageia:9 python-django 0 4.1.13-1.2.mga9
SUSE:Linux Enterprise Module for Package Hub 15 SP6 python-Django 0 4.2.11-150600.3.9.1
SUSE:Package Hub 15 SP5 python-Django 0 2.2.28-bp155.7.18.1
Ubuntu:20.04:LTS python-django 0 2:2.2.12-1ubuntu0.25
Ubuntu:22.04:LTS python-django 0 2:3.2.12-2ubuntu1.14
Ubuntu:24.04:LTS python-django 0 3:4.2.11-1ubuntu1.3
Ubuntu:24.10 python-django 0 3:4.2.15-1ubuntu1
Ubuntu:25.04 python-django 0 3:4.2.15-1ubuntu1
Ubuntu:Pro:14.04:LTS python-django 0 No fix
Ubuntu:Pro:16.04:LTS python-django 0 No fix
Ubuntu:Pro:18.04:LTS python-django 0 1:1.11.11-1ubuntu1.21+esm7
openSUSE:Leap 15.5 python-Django 0 2.0.7-150000.1.33.1
openSUSE:Leap 15.5 python-Django 0 2.2.28-bp155.7.18.1
openSUSE:Leap 15.6 python-Django 0 4.2.11-150600.3.9.1
openSUSE:Tumbleweed python-Django 0 5.1.1-1.1
openSUSE:Tumbleweed python-Django4 0 4.2.16-1.1
openSUSE:Tumbleweed python-Django6 0 6.0-1.1
pypi Django 5.0 No fix
pypi Django 5.1 No fix

Related vulnerabilities