Skip to main content

Lack of data validation - Headers

Need

Implementation of proper data validation for HTTP headers

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 HttpResponse

def some_view(request):
# Get the value of the 'X-Forwarded-For' header
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')

# Use the value of the header directly in the response
response = HttpResponse()
response['X-Forwarded-For'] = x_forwarded_for

return response

In the above Python code, we are using Django framework to create a view. The view is getting the value of the 'X-Forwarded-For' header from the request and directly using it in the response without any validation.

The 'X-Forwarded-For' header is used to identify the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.

The problem here is that this header can be easily manipulated by an attacker. If an attacker changes the 'X-Forwarded-For' header, our server will blindly trust this header and use its value in the response. This could lead to various types of attacks such as Cross-Site Scripting (XSS) or compromise the integrity of the stored information.

The vulnerability lies in the fact that the code does not validate or sanitize the 'X-Forwarded-For' header value before using it. This means that an attacker can inject malicious values into this header to manipulate the server's response or even execute arbitrary code on the server.

Steps

  • Validate the 'X-Forwarded-For' header value before using it. This can be done by checking if the value is in a list of known, trusted proxies.
  • Sanitize the 'X-Forwarded-For' header value to prevent XSS attacks. This can be done by encoding the value to escape any potentially harmful characters.
  • Consider using a library or framework that provides built-in functions for header validation and sanitization.

Compliant code

from django.http import HttpResponse
from django.core.exceptions import SuspiciousOperation

def some_view(request):
# Get the value of the 'X-Forwarded-For' header
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')

# List of known, trusted proxies
trusted_proxies = ['192.168.0.1', '192.168.0.2'] # Update this list with your trusted proxies

# Validate the 'X-Forwarded-For' header
if x_forwarded_for and x_forwarded_for not in trusted_proxies:
raise SuspiciousOperation('Invalid X-Forwarded-For header value')

# Sanitize the 'X-Forwarded-For' header value
x_forwarded_for = x_forwarded_for.replace('<', '&lt;').replace('>', '&gt;')

# Use the value of the header in the response
response = HttpResponse()
response['X-Forwarded-For'] = x_forwarded_for

return response

The updated code now includes validation and sanitization of the 'X-Forwarded-For' header value.

Firstly, we define a list of known, trusted proxies. This list should be updated with the IP addresses of your trusted proxies.

Next, we validate the 'X-Forwarded-For' header value by checking if it is in our list of trusted proxies. If the header value is not in the list, we raise a SuspiciousOperation exception, which is a built-in Django exception for handling suspicious operations.

After validating the header value, we sanitize it to prevent XSS attacks. We do this by replacing the '<' and '>' characters with their HTML encoded equivalents. This prevents any potentially harmful characters from being interpreted as HTML or JavaScript code.

Finally, we use the sanitized and validated header value in the response.

This approach ensures that only valid, trusted header values are used, and that any potentially harmful characters are properly escaped. This helps to prevent XSS attacks and maintain the integrity of the stored information.

References