Skip to main content

Sensitive information in source code - Dependencies

Need

Secure storage of sensitive information in separate, protected environments

Context

  • Usage of Python 3 for scripting and application development
  • Usage of Django for building web applications in Python
  • Usage of psycopg2 for connecting to and interacting with PostgreSQL databases

Description

Non compliant code

# settings.py
SECRET_KEY = 'your-secret-key'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'your-database-name',
'USER': 'your-database-user',
'PASSWORD': 'your-database-password',
'HOST': 'localhost',
'PORT': '5432',
}
}

The above code is part of a Django settings file (settings.py). This file is responsible for the configuration of the Django project. The SECRET_KEY and DATABASES dictionary contain sensitive information that should not be exposed in the source code.

In this case, the SECRET_KEY is a secret unique key for each Django project. It is used to provide cryptographic signing, and should be kept safe. If a malicious user gets this key, they could potentially perform attacks on your application.

The DATABASES dictionary is a configuration for the database connections. It includes the name of the database, the user, the password, the host, and the port. If these details are exposed, an attacker could gain unauthorized access to the database, leading to data leakage or corruption.

Storing these sensitive details in the source code is a bad practice. It exposes them to anyone who has access to the source code, including potential attackers. This is a significant security risk and should be avoided.

Steps

  • Remove the sensitive information from the source code. This includes the SECRET_KEY, database name, user, password, host, and port.
  • Store the sensitive information in environment variables. This can be done in the operating system's settings or in a separate configuration file that is not included in the version control system.
  • Use a secure method to access these environment variables in your application. For example, in Django, you can use the os.environ.get() function to get the value of an environment variable.
  • Ensure that the configuration file or environment variables are properly secured. This means they should only be accessible by the necessary personnel or processes.
  • Regularly rotate and change these sensitive values to reduce the risk if they are somehow exposed.

Compliant code

# settings.py
import os

SECRET_KEY = os.environ.get('SECRET_KEY')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST'),
'PORT': os.environ.get('DB_PORT'),
}
}

The updated code removes the sensitive information from the source code and instead retrieves these values from environment variables. This is done using the os.environ.get() function, which is a secure method to access these variables.

The SECRET_KEY, DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, and DB_PORT are all expected to be set in the environment where this application is running. These can be set in the operating system's settings or in a separate configuration file that is not included in the version control system.

This approach ensures that the sensitive information is not exposed in the source code and reduces the risk of this information being accessed by unauthorized individuals or processes. It also allows for easy rotation and change of these sensitive values, further reducing the risk if they are somehow exposed.

Remember to secure the configuration file or environment variables properly. This means they should only be accessible by the necessary personnel or processes. Regularly rotate and change these sensitive values to reduce the risk if they are somehow exposed.

References