Django Do I need to take any further step for secure my user password?

I setup an password reset system in my django website. Where user first to need submit his email address then my website sending an password rest code to his email. He need to be enter his verification code and new password in password reset page. If he entered right verification code then his password will be change and redirect to login page. I have few question:

  1. is there any security risk in my password reset system?
  2. How .set_password() working for save user password? does it using any encryption method?
  3. Most important question : can user change his user_id during changing password? if yes then how to stop him to change password password if user_id changed?

here is my code:

the first function sending verification code to user email:

def ForgetPasswordSendCode(request):
    if request.method == "POST":
       email = request.POST["email"]
       User = get_user_model()
       if not User.objects.filter(email=email).first():
           messages.success(request, "Invalid mail")
           return redirect('members:reset-password') 
       user_obj = User.objects.get(email=email)
       
       reset_code = str(rand_number_mail())
      
       
       profile_obj = UserProfile.objects.get(user=user_obj)
       profile_obj.forget_password_token = reset_code 
       profile_obj.save()


       current_site = get_current_site(request)
       subject = 'Password Reset Code'
       context = {
                    'user_first_name':  user_obj.first_name ,
                    'user_last_name':  user_obj.last_name ,
                    'domain': current_site.domain,
                    'reset_code': reset_code
                 
                }
       html_body = render_to_string('mail/resetpassword-mail.html', context)
       to_email = request.POST["email"] 
       email = EmailMultiAlternatives(subject=subject,from_email='noreply@farhyn.com',to=[to_email]) 
       email.attach_alternative(html_body, "text/html") 
       email.send(fail_silently=False)
      
       messages.success(request, "password reset code sent to your email address")
       return redirect('members:change-password')     
    return render(request, 'members/password_reset_form.html')   

This second function changing user password. User need to be enter his verification code and new password.

def ChangePassWordPage(request):
    User = get_user_model()
    try:
        if request.method == "POST":
            
            forget_password_token = request.POST["forget_password_token"]
            password1 =  request.POST["password1"]
            password2 =  request.POST["password2"]
           
            if not UserProfile.objects.filter(forget_password_token=forget_password_token):
                messages.warning(request, "Invalid Code. Enter the correct code without any space")
            if password1 != password2:
                    messages.warning(request,"The two password fields didn’t match")
                    return redirect('members:change-password')
            user_profile = UserProfile.objects.get(forget_password_token=forget_password_token)
            user_id = user_profile.user_id
            user_obj = User.objects.get(id=user_id)
            if password1 == password2:
                user_obj.set_password(password1)
                user_obj.save()
                reset_code = str(rand_number_mail())
                user_profile.forget_password_token = reset_code
                user_profile.save()

                messages.success(request,"Your password sucessfully changed")
                return redirect('members:login') 
    
    except Exception as e:
        print('wrong user')

     
         
    return render(request,'members/password_change.html')  

You shouldn’t be creating this mechanic yourself.

Django has a fully-functional, tested, and verified password reset system.
See the information in the Authentication Views docs

Yes, there’s at least one security risk I can see in your code.

See Password management in Django | Django documentation | Django

1 Like

Can you please tell me what type of security risk have in my my code and how to solve it ? If I use django default password reset system then is it possible to customize email templates and html pages? If yes then any documents how to customize ?

See the docs that I linked to in my previous response. The answers to both your questions are in there.

1 Like

Only one question now I have. You said there is an security risk in my custom password reset system but you didn’t tell details. What type of security risk?

The fundamental risk is that you attempted to “roll your own security” system without fully understanding what’s involved in making such an environment secure.
I’m not going to bother detailing the three different ways that I can currently see to “attack” your proposed solution.

1 Like

Is if fully secure and safe using django built in forget password system???

The concept of a system being “secure” is not a binary question. You cannot honestly ask the question “Is it fully secure and safe” for any system and come up with an answer other than “No.” Security is a sliding scale, not an “is” or “isn’t” issue.

The question that needs to be asked is “Is it safe enough for my requirements.”

For 99+% of the situations for which someone will be using Django, the answer to that question is “Yes”.

Thanks KenWhitesell I got my answare

KenWhitesell I have few question after implementing django default reset password system.

question1: reset password link is not expiring until user changed the password. The link can be used only once which is good. But as it don’t have any expiration time so I think it will be good to set an expiration on every reset password link. is it possible to add expiring time ?

question2: user redirecting to confirmation page after submitting email or reset password. I can also directly go the confirmation page using link. Can I restrict to show confirmation page if user didn’t came from password reset page(where he was submitting email or resetting password). I have two confirmation page. One for submitting email and another for resetting password.

urls.py

#submitting email for reset password
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='password/password_reset_complete.html'), name='password_reset_complete'), password

#confirmation page after submitting email
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(template_name='password/password_reset_done.html'), name='password_reset_done'),

path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name="password/password_reset_confirm.html"), name='password_reset_confirm'),

#confirmation page after reset password
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='password/password_reset_complete.html'), name='password_reset_complete'),

question3 Django default password reset system 99.99% secure but what happen if someone want to use opt(sent an password reset code to user mobile number) system for resetting password instead of using django default password reset system. what will be your suggestion for this? What type of security step we should take for this type of custom password reset system?

Hello @MDFARHYN I will try to help:

Sure, there is a built-in setting for that, just:

PASSWORD_RESET_TIMEOUT = 3600

In your settings file and it will expire in one hour. The default is for 3 days.

That is difficult, and I think unnecessary, read the documentation about it. The point of the coders of the authentication system is not to expose the information about the email address in order to avoid attacks. But you can add a attribute to de anonymous user session in order to keep track if the user has entered a correct email address.

You can use a Python library for that. For example PyOTP can be used in combination with Google Authenticcator.

I recommend you to follow this tutorial and read all the documentation in order to understand the built-in Django Authentication System.

A great and easy alternative is to use the high quality package Django AllAuth, with it you can rely the authentication in a secure password system like Google G-suite.

1 Like

@Rigo-Villalta Thanks for your great explanation