Intro: As a seasoned Django Master and a discerning GitHub Appraiser, my journey involves not only crafting sophisticated Django packages but also delving into the GitHub project repositories of my disciples. In this quest, I often come across projects that exhibit vulnerability and insecurity. Let's explore some of the common pitfalls I've observed during my ventures.
Common Mistakes:
Vulnerable SECRET_KEY:
One of the prevalent mistakes I encounter is the exposure of the SECRET_KEY. This crucial piece of information should always be guarded with the utmost care.
Vulnerable API_KEY:
Similar to SECRET_KEY, API_KEYs are often left unprotected. This oversight can lead to potential security breaches, compromising the integrity of your project.
Vulnerable DATABASE:
Exposing database credentials is another pitfall. It's essential to shield this sensitive information from prying eyes to prevent unauthorized access.
Using Class Based Views (NEVER USE IT):
While not a security risk per se, It is Risking Yourself to Brain Damage just by it's Use or by someone else when they are trying to box you.
NEVER USE CLASS BASED VIEWVulnerable DEBUG status:
Keeping the DEBUG mode on in a production environment is a significant security flaw. This can expose sensitive information and open the door to potential exploits.
Vulnerable DATA:
Mishandling and exposing critical data within your project can have severe consequences. Proper precautions must be taken to ensure data security.
Preventing Mistakes
To tackle these common mistakes, I recommend employing a robust solution – Python-decouple.
Python-decouple:
Python-decouple is a Django package that advocates for a strict separation of settings from code. The solution lies in creating a .env file housing crucial information such as SECRET_KEY, API_KEY, DEBUG status, SMTP credentials, and external database URLs. By utilizing the config(data_name) method, these values can be accessed from the .env file, ensuring a secure and modular approach.
Why not just Use environment variables and the os.environ method like in python?
Cause It will only return String. and we might need to get a Boolean or some other type of data and stop being so stupid.
example code for .env file:
# .env
SECRET_KEY=my_super_secret_key
DEBUG=True
# Database
DATABASE_URL=postgresql://your_db_user:your_db_password@localhost/your_db_name
# Email settings
EMAIL_HOST=your_email_host
EMAIL_PORT=your_email_port
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your_email_username
EMAIL_HOST_PASSWORD=your_email_password
Example code for the settings.py:
# settings.py
from decouple import config
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config('DEBUG', default=False, cast=bool)
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': config('DATABASE_URL',cast = str),
}
# Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = config('EMAIL_HOST')
EMAIL_PORT = config('EMAIL_PORT', cast=int)
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=True, cast=bool)
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
If You are Using the code from your github repo in production, then you need to either create a .env file inside of the root directory of your production environment.
How does it work?
Decouple always searches for Options in this order:
Environment variables;
Repository: ini or .env file;
Default argument passed to config.
Understanding the CAST argument
By default, all values returned by decouple are strings, after all they are read from text files or the environment.
However, your Python code may expect some other value type, for example:
Django’s DEBUG expects a boolean True or False.
Django’s EMAIL_PORT expects an integer.
Django’s ALLOWED_HOSTS expects a list of hostnames.
Django’s SECURE_PROXY_SSL_HEADER expects a tuple with two elements, the name of the header to look for and the required value.
Did you really need to read this? Maybe you are slow...
Implementation:
Create a .env file with sensitive data.
Use Python-decouple's config(data_name) method to access values.
Configure your version control system (Git) to ignore the .env file, preventing inadvertent exposure.
By adopting Python-decouple and implementing a .env file, you fortify your project against several vulnerabilities in one fell swoop. This proactive approach not only enhances security but also fosters good development practices.