Cracked weak credentials
Need
Enhancement of password security
Context
- Usage of Python 3 for scripting and software development
- Usage of Django for building web applications in Python
Description
Non compliant code
from django.contrib.auth.models import User
def create_user(username, password):
user = User.objects.create_user(username, password=password)
user.save()
This is a simple function that creates a user in a Django application using the Django's built-in User
model. A username and password are passed to the function, which are then used to create a new user.
The vulnerability here lies in the fact that the password is stored as a hash in the database. Django uses the PBKDF2 algorithm with a SHA256 hash, a password stretching mechanism that is considered secure. However, the complexity of the hash is directly proportional to the complexity of the password. If a user chooses a weak password, the resulting hash will also be weak, making it easier for an attacker to crack.
In other words, the function does not enforce any password complexity requirements. A user could choose a password like "password123", which would result in a weak hash that could be easily cracked by an attacker. This is a common vulnerability in many web applications and can lead to unauthorized access to user accounts.
Steps
- Increase the complexity of the password requirements. This could include a minimum length, requiring a mix of uppercase and lowercase letters, numbers, and special characters.
- Implement a password strength meter to give users feedback about the strength of their password during account creation or password change.
- Use a strong, unique salt for each password. Salting adds an extra layer of security to the hashing process.
- Use a slow hash function like bcrypt, scrypt or Argon2. These are designed to be slow and computationally demanding, which makes brute force or dictionary attacks less effective.
- Limit the number of login attempts to prevent brute force attacks.
- Implement multi-factor authentication. This adds an additional layer of security as it requires users to verify their identity using a second factor (like a phone or hardware token) in addition to their password.
- Regularly update and patch your systems to protect against known vulnerabilities.
Compliant code
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
import re
def validate_password(password):
# check for minimum length
if len(password) < 8:
return False
# check for uppercase letter
if not re.search("[A-Z]", password):
return False
# check for lowercase letter
if not re.search("[a-z]", password):
return False
# check for digit
if not re.search("[0-9]", password):
return False
# check for special characters
if not re.search("[!@#$%^&*()]", password):
return False
return True
def create_user(username, password):
if not validate_password(password):
raise ValueError("Password does not meet complexity requirements")
hashed_password = make_password(password)
user = User.objects.create_user(username, password=hashed_password)
user.save()
The updated code includes a function validate_password
that checks the complexity of the password. It ensures that the password is at least 8 characters long and includes at least one uppercase letter, one lowercase letter, one digit, and one special character.
In the create_user
function, before creating a user, it validates the password using the validate_password
function. If the password does not meet the complexity requirements, it raises a ValueError.
The password is then hashed using Django's make_password
function before being stored in the database. This function uses the PBKDF2 algorithm with a SHA256 hash, a password stretching mechanism that is recommended by NIST. It also automatically handles the creation of a random salt for each password.
This code does not include measures to limit login attempts or implement multi-factor authentication. These would need to be implemented elsewhere in your application. Regular system updates and patches are also crucial to maintain security.