Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 7, 2025

Fixes a security vulnerability in django-allauth 65.x where the ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS setting defaults to True, causing emails to be sent to unknown email addresses during password reset. This reveals that accounts don't exist and enables account enumeration attacks.

Problem

django-allauth 65.x introduced ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS which defaults to True. When enabled, allauth calls send_unknown_account_mail() for non-existent email addresses during password reset, revealing that the account doesn't exist.

Solution

Set ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False in blt/settings.py to disable this behavior and prevent account enumeration attacks.

Changes

  • Configuration Fix (blt/settings.py)

    • Added ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False with security comment
    • Prevents allauth from sending emails to unknown accounts
  • Tests (website/tests/test_api.py)

    • Added TestPasswordResetUnknownEmail with tests verifying:
      • Unknown email: 200 response, no email sent
      • Known email: 200 response, email sent
  • Documentation (docs/security/password-reset-security.md)

    • Security implementation details
    • Critical configuration section explaining ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS
    • Attack prevention mechanisms (enumeration, timing, spam)
    • Code locations and testing procedures
  • Resolution summary (docs/ISSUE_RESOLUTION_SUMMARY.md)

    • Detailed analysis of allauth 65.x issue
    • Implementation details showing the problem and fix

Current behavior

# Both requests return HTTP 200 with identical message
POST /auth/password/reset/ {"email": "unknown@example.com"}
# → 200 OK, NO email sent (fixed by ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False)

POST /auth/password/reset/ {"email": "known@example.com"}  
# → 200 OK, email sent

Testing

  • ✅ All password reset tests pass
  • ✅ Pre-commit hooks pass
  • ✅ Code review: No issues
  • ✅ Security scan: No vulnerabilities
Original prompt

do not send emails for unknown accounts


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 7, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI and others added 4 commits December 7, 2025 17:04
…counts

Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com>
Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com>
Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com>
Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com>
Copilot AI changed the title [WIP] Remove email notifications for unknown accounts Verify and document password reset security - no emails sent to unknown accounts Dec 7, 2025
Copilot AI requested a review from DonnieBLT December 7, 2025 17:15
@DonnieBLT
Copy link
Collaborator

@copilot I mesn the allauth emails thst are sent when an emsil doesnt exist

…N_ACCOUNTS = False)

Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 9, 2025

@copilot I mesn the allauth emails thst are sent when an emsil doesnt exist

You're absolutely right! I investigated and found that django-allauth 65.x introduced the ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS setting which defaults to True. This causes allauth to send emails to unknown accounts via send_unknown_account_mail().

Fixed in commit 98b1846 by setting ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False in blt/settings.py.

The tests now verify that NO emails are sent to unknown accounts, preventing account enumeration attacks.

Copilot AI changed the title Verify and document password reset security - no emails sent to unknown accounts Fix: Prevent allauth from sending emails to unknown accounts during password reset Dec 9, 2025
@github-actions github-actions bot added the files-changed: 4 PR changes 4 files label Dec 9, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

⚠️ New Markdown Files Detected

This PR adds the following new .md file(s):

  • docs/ISSUE_RESOLUTION_SUMMARY.md
  • docs/security/password-reset-security.md

Please remove these markdown files from the PR. If you believe this file is necessary, please create an issue to discuss it with the maintainers before adding it.

Thank you for your contribution! 🙏

@DonnieBLT DonnieBLT marked this pull request as ready for review December 9, 2025 06:54
Copilot AI review requested due to automatic review settings December 9, 2025 06:54
@github-actions github-actions bot added files-changed: 3 PR changes 3 files and removed files-changed: 4 PR changes 4 files labels Dec 9, 2025
@github-actions github-actions bot added pre-commit: passed Pre-commit checks passed files-changed: 2 PR changes 2 files and removed files-changed: 3 PR changes 3 files labels Dec 9, 2025
Comment on lines +348 to +350
# Security: Do not send emails to unknown accounts during password reset
# This prevents account enumeration attacks
ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False setting likely inverts the intended security behavior, potentially enabling user enumeration.
Severity: HIGH | Confidence: Medium

🔍 Detailed Analysis

The ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False setting, as introduced in blt/settings.py, appears to be incorrectly configured. According to standard django-allauth documentation, setting this to True (the default) is what prevents user enumeration by sending dummy emails to unknown accounts. Setting it to False would likely enable the vulnerability, allowing attackers to determine valid user accounts. The PR's own documentation snippet also suggests that False would prevent sending any mail, which contradicts the goal of preventing enumeration via dummy emails. The existing tests do not adequately validate that this setting controls the behavior, leading to a false sense of security.

💡 Suggested Fix

Verify the ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS setting against django-allauth 65.13.1's actual source code or official documentation. Confirm if the value should be True (not False) to prevent user enumeration, and ensure the setting name is correct.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: blt/settings.py#L348-L350

Potential issue: The `ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False` setting, as introduced in
`blt/settings.py`, appears to be incorrectly configured. According to standard
`django-allauth` documentation, setting this to `True` (the default) is what prevents
user enumeration by sending dummy emails to unknown accounts. Setting it to `False`
would likely enable the vulnerability, allowing attackers to determine valid user
accounts. The PR's own documentation snippet also suggests that `False` would prevent
sending any mail, which contradicts the goal of preventing enumeration via dummy emails.
The existing tests do not adequately validate that this setting controls the behavior,
leading to a false sense of security.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 6368094

@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

👋 Hi @Copilot!

This pull request needs a peer review before it can be merged. Please request a review from a team member who is not:

  • The PR author
  • DonnieBLT
  • coderabbitai
  • copilot

Once a valid peer review is submitted, this check will pass automatically. Thank you!

@github-actions github-actions bot added needs-peer-review PR needs peer review tests: passed Django tests passed labels Dec 9, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a security vulnerability in django-allauth 65.x by configuring the application to prevent account enumeration attacks during password reset. The change ensures that the system maintains consistent API responses while only sending emails to registered accounts, following OWASP security best practices.

Key Changes

  • Security Configuration: Added ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False setting to prevent emails being sent to unknown accounts
  • Test Coverage: Implemented comprehensive tests verifying that unknown accounts receive no emails while maintaining consistent 200 OK responses
  • Documentation: Created detailed security documentation explaining the implementation, attack prevention, and maintenance guidelines

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
blt/settings.py Added critical security setting ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False with explanatory comments to prevent account enumeration attacks
website/tests/test_api.py Implemented TestPasswordResetUnknownEmail test class with two tests verifying correct behavior for both known and unknown email addresses
docs/security/password-reset-security.md Comprehensive security documentation covering implementation details, configuration requirements, attack prevention mechanisms, and maintenance guidelines
docs/ISSUE_RESOLUTION_SUMMARY.md Detailed analysis document explaining the django-allauth 65.x issue, the fix implementation, and verification results

Comment on lines +257 to +269
print("\nTest: Password reset for unknown email")
print(f"Response status: {response.status_code}")
print(f"Response data: {response.json() if response.status_code == 200 else response.content}")
print(f"Emails sent: {len(mail.outbox)}")

# The response should be 200 OK to not reveal account existence
self.assertEqual(response.status_code, 200)

# But NO email should actually be sent for non-existent accounts
self.assertEqual(len(mail.outbox), 0, "No email should be sent for unknown accounts")

print("✓ Correct: No email sent for unknown account")
print("✓ Response still returns 200 OK (doesn't leak account existence)")
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Print statements should be removed from test code before committing. According to the project's coding guidelines, print statements should only be used temporarily during development and removed before committing. Consider using Django's logging framework or removing these debugging statements entirely since the test assertions already verify the expected behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +284 to +295
print("\nTest: Password reset for known email")
print(f"Response status: {response.status_code}")
print(f"Response data: {response.json() if response.status_code == 200 else response.content}")
print(f"Emails sent: {len(mail.outbox)}")

# The response should be 200 OK
self.assertEqual(response.status_code, 200)

# Email SHOULD be sent for existing accounts
self.assertEqual(len(mail.outbox), 1, "Email should be sent for known accounts")

print("✓ Correct: Email sent for known account")
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Print statements should be removed from test code before committing. According to the project's coding guidelines, print statements should only be used temporarily during development and removed before committing. Consider using Django's logging framework or removing these debugging statements entirely since the test assertions already verify the expected behavior.

Copilot uses AI. Check for mistakes.
def test_password_reset_known_email_sends_email(self):
"""Test password reset with known email - should send email"""
# Create a user
user = get_user_model().objects.create_user(
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable user is not used.

Suggested change
user = get_user_model().objects.create_user(
get_user_model().objects.create_user(

Copilot uses AI. Check for mistakes.
@DonnieBLT DonnieBLT merged commit 9c1bb99 into main Dec 9, 2025
24 of 25 checks passed
@DonnieBLT DonnieBLT deleted the copilot/remove-email-for-unknown-accounts branch December 9, 2025 08:41
@github-project-automation github-project-automation bot moved this from Backlog to Done in 📌 OWASP BLT Project Board Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

files-changed: 2 PR changes 2 files needs-peer-review PR needs peer review pre-commit: passed Pre-commit checks passed tests: passed Django tests passed

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants