Sensitive information in source code - API Key - Python

Sensitive information in source code - API Key - Python

Need

Secure storage and retrieval of sensitive information such as API keys

Context

  • Usage of Python 3 for writing and executing Python code
  • Usage of Django for web application development

Description

Non compliant code

        # settings.py in Django

SECRET_KEY = 'your-secret-key'
        
        

In the above code snippet, the SECRET_KEY is hard-coded directly into the Django settings.py file. This key is used for cryptographic signing in the Django framework, and it's crucial to keep it secret.

However, storing this key directly in the source code is a serious security vulnerability. If the source code is ever exposed, for example, through a version control system or by being accidentally published, then the SECRET_KEY is exposed as well. This could allow an attacker to manipulate the application's cryptographic signing, leading to a potentially severe security breach.

Moreover, the key is stored in plain text, which means it can be easily read and used by anyone who has access to the source code. This is a violation of the principle of least privilege, which states that code, users, and applications should only have the minimum privileges necessary to perform their function.

To mitigate this vulnerability, the SECRET_KEY should be stored in a secure and confidential manner, such as in an environment variable or a secure key management system, and it should not be stored in the source code.

Steps

  • Remove the hard-coded secret key from the source code.
  • Store the secret key in an environment variable. This way, the key is not exposed in the code and can be changed without modifying the code.
  • Use a secure method to set the environment variable, such as a secure shell script or a configuration management tool.
  • Ensure that the environment variable is not logged or exposed in any error messages or logs.
  • In your application, retrieve the secret key from the environment variable.
  • Ensure that the application fails to start if the secret key environment variable is not set. This prevents the application from running with a default or hard-coded key if the environment variable is not correctly configured.

Compliant code

        # settings.py in Django
import os

SECRET_KEY = os.environ.get('SECRET_KEY')

if not SECRET_KEY:
    raise ValueError("No SECRET_KEY set for Django application")
        
        

The above code is a fix for the vulnerability in the Django settings file. The SECRET_KEY is no longer hard-coded in the source code. Instead, it is retrieved from an environment variable named 'SECRET_KEY'.

The os.environ.get('SECRET_KEY') line retrieves the value of the 'SECRET_KEY' environment variable. If the environment variable is not set, os.environ.get() will return None, and the SECRET_KEY variable will be None.

The following lines of code:

                if not SECRET_KEY:
    raise ValueError("No SECRET_KEY set for Django application")

            


check if the SECRET_KEY is None. If it is, this means that the 'SECRET_KEY' environment variable was not set, and the application raises a ValueError with a descriptive error message. This prevents the application from running without a secret key, which would be a serious security risk.

This fix ensures that the secret key is not exposed in the source code and that it can be changed without modifying the code. It also ensures that the application does not run if the secret key is not correctly configured.

Remember to set the 'SECRET_KEY' environment variable in a secure way, such as using a secure shell script or a configuration management tool, and ensure that it is not logged or exposed in any error messages or logs.

References