Data uniqueness not properly verified
Need
Enforce proper data uniqueness verification
Context
- Usage of Python 3 for general-purpose programming and scripting
- 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=200)
email = models.EmailField(max_length=200)
In the above code snippet, we have a Django model called User
with fields username
and email
.
The vulnerability lies in the fact that there are no constraints set to ensure the uniqueness of username
and email
fields. This means that multiple users can register with the same username
or email
which should not be the case as these fields should be unique to each user.
An attacker could potentially exploit this vulnerability by registering multiple accounts with the same username
or email
. This could lead to various issues including impersonation, data inconsistency, and could also interfere with functionalities like password reset, where the application might not be able to determine the correct account to reset the password for, if there are multiple accounts with the same email.
Steps
- Add unique=True attribute to the fields that need to be unique such as username and email.
- Use Django's built-in form validation to check for uniqueness before saving the data.
- Handle the IntegrityError exception that Django raises when trying to save non-unique data.
- Consider using Django's get_or_create method to avoid creating duplicate entries.
Compliant code
from django.db import models
from django.core.exceptions import ValidationError
class User(models.Model):
username = models.CharField(max_length=200, unique=True)
email = models.EmailField(max_length=200, unique=True)
def clean(self):
# Check for existing username or email
if User.objects.filter(username=self.username).exists():
raise ValidationError("Username already exists.")
if User.objects.filter(email=self.email).exists():
raise ValidationError("Email already exists.")
def save(self, *args, **kwargs):
self.clean()
return super(User, self).save(*args, **kwargs)
The updated code now includes the unique=True
attribute for both the username
and email
fields in the User
model. This ensures that Django's ORM will enforce uniqueness at the database level.
In addition to this, we have overridden the clean
method of the model. This method is called before data is saved to the database. In this method, we check if a user with the same username or email already exists in the database. If such a user exists, we raise a ValidationError
.
Finally, we override the save
method of the model. In this method, we call the clean
method to perform our custom validation before calling the save
method of the superclass to actually save the data to the database.
This way, we ensure that the uniqueness of the username and email is validated at two levels - at the database level and at the application level. This provides a robust defense against attempts to create users with duplicate usernames or emails.