Skip to main content

Weak credential policy - Password strength

Need

Implementation of a strong password policy

Context

  • Usage of Python 3 for writing and running Python code
  • Usage of Django for building web applications

Description

Non compliant code

from django.contrib.auth.models import User

def create_user(request):
username = request.POST['username']
password = request.POST['password']

user = User.objects.create_user(username=username, password=password)
user.save()

The above code is a simple Django view function that creates a new user in the system. It takes a username and password from a POST request and uses Django's built-in create_user method to create a new user with these credentials.

However, this code is vulnerable because it doesn't enforce any password strength requirements. A user could potentially create an account with a weak password such as "123456" or "password", which are easy to guess or crack with brute force attacks.

A stronger password policy might include requirements for:

  • Minimum length: A longer password is generally more secure than a short one.
  • Complexity: The password should include a mix of uppercase and lowercase letters, numbers, and special characters.
  • Non-obviousness: The password should not include easily guessed information like the user's name or username.

Without these checks in place, the user's account (and any data it has access to) is at risk.

Steps

  • Import the 'validate_password' function from 'django.contrib.auth.password_validation'.
  • Before creating the user, call the 'validate_password' function with the password as an argument.
  • The 'validate_password' function will raise a 'ValidationError' if the password does not meet Django's default password validation rules. You should catch this exception and handle it appropriately.
  • If the password is valid, proceed to create the user as before.

Compliant code

from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.contrib.auth.password_validation import validate_password

def create_user(request):
username = request.POST['username']
password = request.POST['password']

try:
validate_password(password)
except ValidationError as e:
return {'status': 'error', 'message': str(e)}

user = User.objects.create_user(username=username, password=password)
user.save()
return {'status': 'success', 'message': 'User created successfully'}

The updated code now includes a password validation step before creating a new user. This is done by importing the validate_password function from django.contrib.auth.password_validation.

The validate_password function is called with the password as an argument. If the password does not meet Django's default password validation rules, the function will raise a ValidationError.

This exception is caught and handled by returning a dictionary with a status of 'error' and a message containing the error details.

If the password is valid, the user is created and saved as before, and a success message is returned.

This way, the system now enforces a strong credential policy, mitigating the risk of weak passwords.

References