Non-encrypted confidential information - Keys - Python

Non-encrypted confidential information - Keys - Python

Need

Secure storage of confidential information

Context

  • Usage of Python 3 for scripting and application development
  • Usage of Django for building web applications in Python

Description

Non compliant code

        from django.db import models

class User(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
        
        

In the code snippet above, we have a Django model named User that stores user information such as username and password. However, the password is stored in plain text which is a clear vulnerability.

If an attacker gains access to the database, they can easily read the passwords due to the lack of encryption. This is a serious security risk as it exposes sensitive user information.

The CharField data type in Django is used to store strings of characters, making it suitable for storing text-based data. However, it does not provide any form of encryption or hashing, making it unsuitable for storing sensitive information such as passwords.

In a secure system, passwords should never be stored in plain text. They should be hashed using a strong, cryptographic hash function. When a user logs in, the system should hash the entered password and compare it to the stored hashed password. This way, even if an attacker gains access to the database, they cannot determine the original password from the hashed version.

Steps

  • Import Django's built-in User model instead of creating a custom one.
  • Use Django's built-in authentication system which automatically handles password hashing and storage.
  • If a custom model is necessary, use Django's PasswordField instead of CharField for the password field. This will automatically hash and salt the password.
  • Never store passwords in plain text. Always hash and salt passwords before storing them.
  • Consider using additional security measures such as two-factor authentication.

Compliant code

        from django.contrib.auth.models import User
from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # other fields as necessary
        
        

In the fixed code, we are using Django's built-in User model instead of creating a custom one. The User model in Django comes with fields for username and password, and it automatically handles password hashing and storage. This means that when a password is saved, Django will automatically hash and salt the password, which is a crucial security measure.

The UserProfile model is a custom model that extends the User model. It has a OneToOneField to the User model, which means that each user has one and only one profile. This model can be used to add additional user information.

By using Django's User model and its built-in authentication system, we avoid storing passwords in plain text, which is a serious security vulnerability. An attacker who gains access to the database would be able to see all users' passwords if they were stored in plain text. By hashing and salting passwords, even if an attacker gains access to the database, they would not be able to see the actual passwords.

In addition to using Django's built-in authentication system, consider using additional security measures such as two-factor authentication. This adds an extra layer of security by requiring users to provide two forms of identification before they can access their account.

References