Skip to main content

Lack of data validation - Special Characters

Need

Implementation of data validation to prevent the entry of special characters

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 import forms

class UserForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput())

In the above Django form for user registration, the username and password fields are both CharFields. This means that they accept any character input, including special characters.

The vulnerability here is the lack of data validation for special characters. An attacker could potentially exploit this by entering special characters that could lead to SQL injection, Cross-site Scripting (XSS), or other types of attacks.

For example, if an attacker enters a username like ' OR '1'='1, it could lead to an SQL injection attack. Similarly, if an attacker enters a username like <script>evil_script_here</script>, it could lead to an XSS attack if the username is displayed unsanitized somewhere on the site.

The lack of validation also means that the system may not handle special characters correctly in all cases, leading to potential errors or unexpected behavior.

Steps

  • Import the necessary Django validation modules.
  • Create a custom validation function that checks for special characters in the input fields.
  • Apply this validation function to the 'username' and 'password' fields in the UserForm class.
  • Ensure that the validation function raises a ValidationError if special characters are detected.
  • In the form's clean() method, call the custom validation function for each field that needs to be checked.
  • Test the form to ensure that it correctly rejects inputs with special characters.

Compliant code

from django import forms
from django.core.exceptions import ValidationError
import re

class UserForm(forms.Form):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=forms.PasswordInput())

def clean_username(self):
username = self.cleaned_data.get('username')
if re.search(r'\\W', username):
raise ValidationError("Username should not contain special characters.")
return username

def clean_password(self):
password = self.cleaned_data.get('password')
if re.search(r'\\W', password):
raise ValidationError("Password should not contain special characters.")
return password

The above code fixes the vulnerability by adding data validation to the 'username' and 'password' fields in the UserForm class.

Firstly, the necessary Django validation module, ValidationError, is imported. This module is used to raise an error when the validation fails.

A regular expression (regex) module is also imported. This is used to check for special characters in the input fields.

Two new methods, clean_username and clean_password, are added to the UserForm class. These methods are automatically called when the is_valid() method is called on a form instance.

In these methods, the cleaned_data.get() function is used to retrieve the value of the 'username' and 'password' fields.

The re.search(r'\\W', username) and re.search(r'\\W', password) functions are used to check if the 'username' and 'password' fields contain any special characters. The '\W' pattern in the regex function matches any non-alphanumeric character.

If a special character is found, a ValidationError is raised with a message indicating that special characters are not allowed.

If no special characters are found, the 'username' and 'password' values are returned as they are.

This way, the form now validates that the 'username' and 'password' fields do not contain any special characters, thus fixing the vulnerability.

References