#31139: PasswordResetView return success message for emails not in database also
-------------------------------------+-------------------------------------
     Reporter:  SANYAM MITTAL        |                    Owner:
         Type:                       |  sanyam19092000
  Cleanup/optimization               |                   Status:  new
    Component:  contrib.auth         |                  Version:  master
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  1
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  1                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by SANYAM MITTAL):

 * status:  closed => new
 * needs_docs:  0 => 1
 * resolution:  wontfix =>


Comment:

 Thanks for the Reference,

 As mentioned in documentation
 
[​https://docs.djangoproject.com/en/stable/topics/auth/default/#django.contrib.auth.views.PasswordResetView]

 ''** This prevents information leaking to potential attackers**''

 Facebook also raises a Validation Error when non registered email is
 entered
 [https://www.facebook.com/login/identify/?ctx=recover]
 ----

 Although a potential attacker can easily get these information from Sign-
 Up/Register page as **Validation error is raised when a Duplicate Email
 Address** is entered during sign-up.

 If there's **not a Unique email Validation** during Sign-up there are
 chances that multiple users get registered with same email (if user
 mistakenly types someone else's email) and Password Reset email is sent
 multiple times for different Users which is more risky.

 ----

 **If still it prevents Information leak by any other ways** then
 documentation should be more accurate and should have a sample or
 **Suggestion method** to achieve unique email Validation with current
 PasswordResetForm like

  If you want to provide an error message in this case, you can subclass
 **PasswordResetForm** and use the **form_class attribute**.
 {{{
 class PasswordResetForm(forms.Form):
     error_messages = {
         'not_registered': _('Email ID is not Registered'),
     }
     email = forms.EmailField(
         label=_("Email"),
         max_length=254,
         widget=forms.EmailInput(attrs={'autocomplete': 'email'})
     )

     def clean_email(self):
         email = self.cleaned_data.get('email')
         users =  self.get_users(email=email)
         flag = False
         for user in users:
             if user:
                 flag = True

         if not flag:
             raise forms.ValidationError(
                 self.error_messages['not_registered'],
                 code='not_registered',
             )
         return email


     def send_mail(self, subject_template_name, email_template_name,
                   context, from_email, to_email,
 html_email_template_name=None):
         """
         Send a django.core.mail.EmailMultiAlternatives to `to_email`.
         """
         subject = loader.render_to_string(subject_template_name, context)
         # Email subject *must not* contain newlines
         subject = 'Testing Purpose'
         body = loader.render_to_string(email_template_name, context)

         email_message = EmailMultiAlternatives(subject, body, from_email,
 [to_email])
         if html_email_template_name is not None:
             html_email = loader.render_to_string(html_email_template_name,
 context)
             email_message.attach_alternative(html_email, 'text/html')

         email_message.send()

     def get_users(self, email):
         """Given an email, return matching user(s) who should receive a
 reset.

         This allows subclasses to more easily customize the default
 policies
         that prevent inactive users and users with unusable passwords from
         resetting their password.
         """
         email_field_name = UserModel.get_email_field_name()
         active_users = UserModel._default_manager.filter(**{
             '%s__iexact' % email_field_name: email,
             'is_active': True,
         })

         return (
             u for u in active_users
             if u.has_usable_password() and
             _unicode_ci_compare(email, getattr(u, email_field_name))
         )

     def save(self, domain_override=None,
 subject_template_name='registration/password_reset_subject.txt',
              email_template_name='registration/password_reset_email.html',
              use_https=False, token_generator=default_token_generator,
              from_email=None, request=None, html_email_template_name=None,
              extra_email_context=None):
         """
         Generate a one-use only link for resetting password and send it to
 the
         user.
         """
         email = self.cleaned_data["email"]
         email_field_name = UserModel.get_email_field_name()
         for user in self.get_users(email):
             if not domain_override:
                 current_site = get_current_site(request)
                 site_name = current_site.name
                 domain = current_site.domain
             else:
                 site_name = domain = domain_override
             user_email = getattr(user, email_field_name)
             context = {
                 'email': user_email,
                 'domain': domain,
                 'site_name': site_name,
                 'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                 'user': user,
                 'token': token_generator.make_token(user),
                 'protocol': 'https' if use_https else 'http',
                 **(extra_email_context or {}),
             }
             self.send_mail(
                 subject_template_name, email_template_name, context,
 from_email,
                 user_email,
 html_email_template_name=html_email_template_name,
             )
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31139#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/071.b0b774f9abfe74bd56c8e89aae2004a9%40djangoproject.com.

Reply via email to