logo

Security controls bypass or absence - Data creation - Python


Need

Enforcement of security controls for data creation


Context

  1. Usage of Python 3 for developing applications and scripts
  2. Usage of Django for building web applications in Python

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 305 - Security controls bypass or absence - Data creation

  • Last updated

    2023/09/18