Business information leak - JFROG - Python

Business information leak - JFROG - Python

Need

Protection of sensitive business information from unauthorized access and leakage

Context

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

Description

Non compliant code

        # settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': 'mydatabasehost.com',
        'PORT': '3306',
    }
}

SECRET_KEY = 'mysecretkey'

# Other settings...
        
        

In the above code, sensitive information such as database credentials (username, password, host) and the Django secret key are hard-coded directly into the settings.py file. This is a serious security vulnerability as anyone who gains access to this code would also gain access to your database and could perform any number of malicious activities, including data theft, data manipulation, or even deletion of the entire database.

Furthermore, if this code is pushed to a public version control system like GitHub, this information would be accessible to anyone on the internet. Even if the repository is private, it is still a security risk as it increases the attack surface
- anyone who gains unauthorized access to the repository would also gain access to the database.

The Django secret key is used for cryptographic signing, and should be kept secret. If an attacker obtains the secret key, they could potentially perform a number of attacks, including session hijacking, data tampering, and privilege escalation.

Finally, if the application is using any other external services that require credentials, those should not be hard-coded into the code either for the same reasons.

Steps

  • Remove hard-coded credentials from the code. These include database credentials and secret keys.
  • Use environment variables to store sensitive information. This way, the credentials are not exposed in the code.
  • Implement a secure method to access these environment variables, such as using a configuration management system.
  • Encrypt sensitive data. Even if someone gains access to the environment variables, they won't be able to understand the information without the decryption key.
  • Regularly rotate and change these credentials to minimize the risk if they are compromised.
  • Implement access controls and permissions to limit who can access these credentials.
  • Use a secure vault service to store sensitive information. These services provide an extra layer of security by encrypting data and controlling access.

Compliant code

        import os
from django.core.exceptions import ImproperlyConfigured

# settings.py

def get_env_variable(var_name):
    """ Get the environment variable or return exception """
    try:
        return os.environ[var_name]
    except KeyError:
        error_msg = "Set the {} environment variable".format(var_name)
        raise ImproperlyConfigured(error_msg)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': get_env_variable('DB_NAME'),
        'USER': get_env_variable('DB_USER'),
        'PASSWORD': get_env_variable('DB_PASSWORD'),
        'HOST': get_env_variable('DB_HOST'),
        'PORT': get_env_variable('DB_PORT'),
    }
}

SECRET_KEY = get_env_variable('SECRET_KEY')

# Other settings...
        
        

The above code has been modified to remove hard-coded credentials and secret keys. Instead, it now uses environment variables to store this sensitive information. This is done using the os.environ method in Python, which retrieves the value of the environment variable specified.

The function get_env_variable(var_name) is defined to get the environment variable or return an exception if the environment variable is not set. This function is then used to get the values for the database name, user, password, host, port, and secret key.

This way, the credentials are not exposed in the code, providing a more secure way to handle sensitive information. It is important to set these environment variables in a secure manner, such as through a configuration management system.

Furthermore, it is recommended to encrypt these environment variables to add an extra layer of security. Even if someone gains access to the environment variables, they won't be able to understand the information without the decryption key.

Regularly rotating and changing these credentials can also help to minimize the risk if they are compromised. Implementing access controls and permissions can limit who can access these credentials.

Finally, consider using a secure vault service to store sensitive information. These services provide an extra layer of security by encrypting data and controlling access.

References