Lack of data validation - Numbers - Python

Lack of data validation - Numbers - Python

Need

Implementation of robust data validation for numbers

Context

  • Usage of Python 3 for writing and executing Python code
  • Usage of Django for building web applications in Python

Description

Non compliant code

        from django.http import JsonResponse

def process_data(request):
    number = request.GET.get('number')
    result = number * 2
    return JsonResponse({"result": result})
        
        

The function process_data in the above code is vulnerable due to the lack of data validation. It retrieves a value from the GET request parameter number and directly uses it to perform an operation ( number * 2), then returns the result in a JsonResponse.

The vulnerability here is that there is no validation to ensure that the number parameter is indeed a number. If a user passes a non-numeric value as the number parameter, it will cause a TypeError at the line result = number * 2 because you can't multiply a non-numeric value by 2.

This not only breaks the current business logic but also leaves the application open to potential attacks. For example, an attacker might exploit this vulnerability to cause a Denial of Service (DoS) by continuously sending requests with non-numeric number parameters, causing the server to throw errors continuously.

In addition, it can negatively impact the business by causing unexpected downtime or malfunction of the service, and it could potentially expose sensitive error information to the users or attackers. It's also a sign of poor data handling and could lead to further potential vulnerabilities.

Steps

  • Firstly, you should never trust user input. Always validate and sanitize it before using it.
  • In this case, the input is expected to be a number. So, you should check if the input is a number before processing it.
  • You can use Python's built-in function `isdigit()` to check if the input is a number.
  • If the input is not a number, you should return an error response.
  • Also, consider using Django's form or model validation features for more complex validation requirements.

Compliant code

        from django.http import JsonResponse

def process_data(request):
    number = request.GET.get('number')
    if not number.isdigit():
        return JsonResponse({"error": "Invalid input. A number is expected."}, status=400)
    result = int(number) * 2
    return JsonResponse({"result": result})
        
        

The updated code now includes a validation check for the input data. The isdigit() function is used to check if the input is a number. This function returns True if all the characters are digits, otherwise False.

If the input is not a number (i.e., isdigit() returns False), an error response is returned with a status code of 400 (Bad Request). The error message in the response indicates that the input is invalid and a number is expected.

If the input is a number, it is converted to an integer using the int() function before it is processed. This is necessary because the isdigit() function only checks if the characters are digits, it does not convert the input to a number. The result of the processing is then returned in the response.

This update ensures that the process_data function only processes valid input, thus preventing potential issues that could arise from processing invalid input. It also provides a clear error message to the client when the input is invalid, allowing them to correct their request.

References