logo

Weak credential policy - Temporary passwords - Python


Need

Implementation of a strong credential policy for temporary passwords


Context

  1. Usage of Python 3 for writing and executing Python code
  2. Usage of Django for building web applications in Python

Description

Insecure Code Example

from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password

def create_temporary_password(user_id):
    user = User.objects.get(pk=user_id)
    temp_password = user.username[::-1]  # Reverse of username
    user.password = make_password(temp_password)
    user.save()

In the above code, we are creating a temporary password for a user. The function `create_temporary_password(user_id)` takes a user's id as an argument, fetches the corresponding user instance from the database, and then sets a temporary password for the user. The temporary password is created by simply reversing the username (`temp_password = user.username[::-1]`). This approach to generating a temporary password is weak and predictable, making it easy for an attacker to guess the password if they know the username. The password is then hashed using Django's `make_password` function and saved to the database (`user.password = make_password(temp_password)`). This code is vulnerable due to its weak credential policy for temporary passwords. The password strength is weak because it's derived from the username in a predictable manner. This can lead to unauthorized access if an attacker can guess the temporary password.

Steps

  1. Implement a strong password policy for temporary passwords. This could include a minimum length, a requirement for a mix of uppercase and lowercase letters, numbers, and special characters.
  2. Avoid using predictable information, such as the reverse of the username, as a temporary password. Instead, generate a random string.
  3. Consider using a library or built-in function to generate secure random passwords.
  4. Ensure that temporary passwords are only used once and prompt the user to change their password after the first login.
  5. Store passwords securely. Use a strong, one-way hashing algorithm to store passwords.

Secure Code Example

import string
import random
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password

def create_temporary_password(user_id):
    user = User.objects.get(pk=user_id)
    temp_password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits + string.punctuation, k=10))
    user.password = make_password(temp_password)
    user.save()
    return temp_password

The updated code now generates a secure temporary password for the user. Here's how it works: 1. We import the necessary libraries. `string` and `random` are Python's built-in libraries. `string` contains various string constant which contains the ASCII characters of all cases. `random` is used to generate random numbers. 2. In the `create_temporary_password` function, we first retrieve the user object from the database using the provided `user_id`. 3. We then generate a random temporary password. The `random.choices()` function returns a list with a randomly selection from the given iterable (in our case, a combination of uppercase and lowercase ASCII letters, digits, and punctuation). We specify that we want a list of 10 elements. The `join()` function then combines this list into a single string. 4. We use Django's `make_password` function to hash the password before storing it in the database. This is a security best practice, as it means that even if someone gains access to the database, they won't be able to see the users' actual passwords. 5. Finally, we save the user object with the updated password. This code ensures that the temporary password is both secure (as it's randomly generated and hashed) and unique to each user. The user should be prompted to change this temporary password after their first login.


References

  • 364 - Weak credential policy - Temporary passwords

  • Last updated

    2023/09/18