Skip to content

Commit

Permalink
fix(account): Prevent enumeration vs messages
Browse files Browse the repository at this point in the history
  • Loading branch information
pennersr committed Jul 10, 2024
1 parent 663c7df commit a671ca6
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 6 deletions.
3 changes: 3 additions & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Security notice
log/print tokens, you will now have to explicitly log the ``token`` field of
the ``SocialToken`` instance.

- Enumeration prevention: the behavior on the outside of an actual signup versus
a signup where the user already existed was not fully identical, fixed.


0.63.3 (2024-05-31)
*******************
Expand Down
4 changes: 1 addition & 3 deletions allauth/account/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,8 @@ def try_save(self, request):
# Don't create a new account, only send an email informing the user
# that (s)he already has one...
email = self.cleaned_data["email"]
adapter = get_adapter()
adapter.send_account_already_exists_mail(email)
resp = flows.signup.prevent_enumeration(request, email)
user = None
resp = adapter.respond_email_verification_sent(request, None)
request.session[flows.login.LOGIN_SESSION_KEY] = EmailVerificationStage.key
else:
user = self.save(request)
Expand Down
15 changes: 15 additions & 0 deletions allauth/account/internal/flows/signup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.urls import reverse

from allauth.account.adapter import get_adapter
from allauth.core.internal.httpkit import get_frontend_url
from allauth.utils import build_absolute_uri


def prevent_enumeration(request: HttpRequest, email: str) -> HttpResponse:
adapter = get_adapter(request)
adapter.send_account_already_exists_mail(email)
adapter.add_message(
request,
messages.INFO,
"account/messages/email_confirmation_sent.txt",
{"email": email, "login": False, "signup": True},
)
resp = adapter.respond_email_verification_sent(request, None)
return resp


def send_unknown_account_mail(request, email):
signup_url = get_signup_url(request)
context = {
Expand Down
1 change: 1 addition & 0 deletions allauth/account/tests/test_signup.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ def test_prevent_enumeration_with_mandatory_verification(
assert resp.status_code == 302
assert resp["location"] == reverse("account_email_verification_sent")
assertTemplateUsed(resp, "account/email/account_already_exists_message.txt")
assertTemplateUsed(resp, "account/messages/email_confirmation_sent.txt")
assert EmailAddress.objects.filter(email="john@example.org").count() == 1


Expand Down
5 changes: 2 additions & 3 deletions allauth/socialaccount/internal/flows/signup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from allauth import app_settings as allauth_settings
from allauth.account import app_settings as account_settings
from allauth.account.adapter import get_adapter as get_account_adapter
from allauth.account.internal.flows.signup import prevent_enumeration
from allauth.account.utils import (
assess_unique_email,
complete_signup,
Expand Down Expand Up @@ -75,9 +76,7 @@ def process_auto_signup(request, sociallogin):
# address. Instead, we're going to send the user an email that
# the account already exists, and on the outside make it appear
# as if an email verification mail was sent.
account_adapter = get_account_adapter(request)
account_adapter.send_account_already_exists_mail(email)
resp = account_adapter.respond_email_verification_sent(request, None)
resp = prevent_enumeration(request, email)
return False, resp
elif app_settings.EMAIL_REQUIRED:
# Nope, email is required and we don't have it yet...
Expand Down

0 comments on commit a671ca6

Please sign in to comment.