Technical information leak - Print Functions - Python

Technical information leak - Print Functions - Python

Need

Prevention of sensitive information exposure through print functions in production environment

Context

  • Usage of Python 3 for developing applications and scripts
  • Usage of Django for building web applications

Description

Non compliant code

        from django.http import HttpResponse
from django.views import View

class MyView(View):
    def get(self, request, *args, **kwargs):
        try:
            # some code here
            pass
        except Exception as e:
            print(e)
            return HttpResponse("There was an error")

        
        

The above python code represents a Django view. When a GET request is made to the endpoint associated with this view, the get method is called.

In this code, we are handling exceptions by printing them directly to stdout using the print function. This is a common practice during development for debugging purposes. However, in a production environment, this can lead to a technical information leak.

The technical information leak vulnerability occurs when sensitive information about the system or application is unintentionally exposed. In this case, the details of any exception that occurs within the try block are printed directly to stdout. This could include information such as stack traces, database queries, configuration details, or other sensitive details that could be useful to an attacker.

In a production environment, this information should be logged to a secure location, not printed to stdout. Furthermore, error messages returned to the user should not contain any sensitive information.

Steps

  • Remove the print statement that outputs the exception.
  • Instead of printing, log the exception using a logging framework. This ensures that the error information is captured and can be reviewed later in a secure manner.
  • Ensure that the logging level is set appropriately for the production environment. Sensitive information should not be logged in production.
  • Customize the error message returned in the HttpResponse to be generic and not reveal any technical information about the error.

Compliant code

        import logging
from django.http import HttpResponse
from django.views import View

logger = logging.getLogger(__name__)

class MyView(View):
    def get(self, request, *args, **kwargs):
        try:
            # some code here
            pass
        except Exception as e:
            logger.error(e)
            return HttpResponse("An unexpected error occurred. Please try again later.")
        
        

The updated code removes the print statement that was previously used to output the exception. Instead, it uses Python's built-in logging framework to log the exception. This ensures that the error information is captured and can be reviewed later in a secure manner.

The logger.error(e) line logs the exception as an error. The logger object is obtained by calling logging.getLogger(__name__), which gets or creates a logger with the name of the current module. This allows the logged errors to be associated with the module where they occurred.

The HttpResponse returned in the case of an exception has been updated to return a generic error message. This message does not reveal any technical information about the error, which helps to prevent information leakage.

Finally, it's important to note that the logging level should be set appropriately for the production environment. Sensitive information should not be logged in production. This can be controlled by setting the logging level on the logger object, or by configuring the logging level in the application's logging configuration.

References