Django Password Requirements Not Enforced

ID

python.django_password_requirements_not_enforced

Severity

low

Resource

Risky Values

Language

Python

Tags

CWE:521, NIST.SP.800-53, OWASP:2021:A7, PCI-DSS:6.5.10, PCI-DSS:6.5.6, django

Description

A password is set within a Django application without enforcing the application’s password policy.

Rationale

Password policies are essential for maintaining security within an application. They ensure that passwords meet certain complexity and strength requirements to reduce the risk of unauthorized access. Failing to enforce these requirements may lead to weak passwords that could be easily compromised by attackers.

In Django applications, proper password validation must be implemented to comply with security standards.

# Example of directly setting a password without validation
user = User.objects.get(username='example')
user.set_password('simplepassword')  # FLAW
user.save()

The example above directly sets a user’s password without verifying if it meets any predefined password policies, such as minimum length, complexity, or the inclusion of special characters.

Remediation

To ensure compliance with password policies, Django offers built-in mechanisms for password validation, which should be utilized to enforce strong password criteria.

from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User

user = User.objects.get(username='example')
new_password = 'ComplexPass123!'

# Validate the password against Django's validators
try:
    validate_password(new_password, user)
    user.set_password(new_password)
    user.save()
except ValidationError as e:
    # Handle the exception by returning validation errors
    print(f"Password validation error(s): {e}")

By using the validate_password method, you ensure that the password adheres to the security policies configured in your Django settings, therefore enhancing the application’s overall security posture.

Configure password validators in settings.py to enforce specific criteria:

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {'min_length': 9},
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
]

Implementing these validators helps ensure passwords are robust and compliant with your security policies.

References

  • CWE-521: Weak Password Requirements.