Cracked weak credentials - Python

Cracked weak credentials - Python

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.

References