Skip to main content

Security controls bypass or absence - Data creation

Need

Enforcement of security controls for data creation

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of Django for building web applications in Python

Description

Non compliant code

from django.db import models

class Policy(models.Model):
name = models.CharField(max_length=100)
beneficiaries = models.ManyToManyField('Beneficiary', related_name='policies')

class Beneficiary(models.Model):
name = models.CharField(max_length=100)

The above code represents a Django model called Policy and another model called Beneficiary. A policy can have multiple beneficiaries, and this relationship is represented by a Many-to-Many relationship between Policy and Beneficiary.

The PolicyView class is a Django view that handles the creation of policies and beneficiaries. In the post method, it first gets the policy name and beneficiary names from the POST request. It then creates a policy with the given name and for each beneficiary name, it creates a beneficiary and adds it to the policy.

The vulnerability here is that there is no restriction on the number of beneficiaries that can be added to a policy. Despite the business rule that a policy should only have four beneficiaries, the current implementation allows the creation of a policy with any number of beneficiaries. This can lead to potential data integrity issues and can also be exploited by an attacker to create policies with a large number of beneficiaries, leading to potential denial of service.

Steps

  • Create a custom save method in the Policy model.
  • In the custom save method, check the count of beneficiaries before saving the policy.
  • If the count of beneficiaries is more than four, raise an exception or return an error message.
  • This will ensure that a policy cannot be saved with more than four beneficiaries, maintaining the integrity of the data.

Compliant code

from django.db import models
from django.core.exceptions import ValidationError

class Policy(models.Model):
name = models.CharField(max_length=100)
beneficiaries = models.ManyToManyField('Beneficiary', related_name='policies')

def save(self, *args, **kwargs):
if self.beneficiaries.count() > 4:
raise ValidationError("A policy cannot have more than four beneficiaries.")
super(Policy, self).save(*args, **kwargs)

class Beneficiary(models.Model):
name = models.CharField(max_length=100)

The code above fixes the vulnerability by adding a custom save method to the Policy model. This method checks the count of beneficiaries before saving the Policy instance. If the count of beneficiaries is more than four, it raises a ValidationError with a message indicating that a policy cannot have more than four beneficiaries.

This ensures that the restriction on the number of beneficiaries is enforced at the model level, preventing the creation of a policy with more than four beneficiaries. This maintains the integrity of the data and prevents the bypassing of this security control.

References