When creating a django web site that connects to a database, It is necessary to provide information about the database, the database user and the password for that user. Here is an example of the database connection in the settings.py file.
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'techreviews', 'USER' : 'postgres', 'PASSWORD': 'P@ssw0rd1', 'HOST' :'localhost', 'PORT' :'', } }
There are several things about this that would give anyone who cares about security indigestion. Too much sensitive information is in plain text. The name of the database could be used for an attack, especially with the name of a user and their password. Especially damaging, in this case, is that the user is "postgres," the default admin user in PostgreSQL. The postgres user has total access to all the databases on the server. The name of the server and the port number could also be sensitive. Here the port number is not stated, but that is only because it is using the default port. Again, an avenue for attack.
In this blog we will set up a new django project in a more secure way. First we will create a dedicated user in PostgreSQL that can only access the one database dedicated to the application. Secondly, we will install a decouple library into django that allows us to create a separate ini or env file to store our sensitive information.
Creating a dedicated user
This part we will do in PostgreSQL's pgAdmin.
Our Project will be to create a web site for a fictional charity called Community Assist. (Yes, I have used this before.) There will be two apps in the project: one for general users and one for employees.
First, we will create the database. To do this right click on databases in pgAdmin and select CREATE/DATABASE. Name the database "comsssistdb."

Click "Save" to create the database.
Now right click on the comassistdb and select "Query Tool." We will use this to write the SQL to create a new role and grant it permissions. We will call the role "communtyapprole." The role will have a password and login privledges. Then we will grant it all privileges on the commassistdb database.
CREATE ROLE communityapprole with password 'P@ssw0rd1' LOGIN; GRANT ALL PRIVILEGES ON DATABASE comassistdb TO communityapprole;
Django needs total control of the database used by the app, but by creating a separate user, the other databases on the server are kept inaccessible.We will add more layers of security later using django's built in authorization libraries and tools.
Setting up the Project
I am making this on a Ubuntu 19.4 machine, but the commands are basically the same on Windows and Macs. I am putting it into a folder called DJangoFiles, which already has django and the virtual environment installed. I activate the virtual environment and create the project commassistproj. Next I create the pubic app commassistapp.
$ source env01/bin/activate $ django-admin startproject commassistproj $ cd commassistproj $ python3 manage.py startapp commassistapp
In Windows the first line would be
env01\scripts\activate
No source." Also "python3" would just be python.
Decoupling: Moving sensitive information out of the settings.py
The first thing to do is to install the decouple library.
pip install python-decouple
In in the settings.py of the project import config from the decouple library
import os from decouple import config
Add a new file to the program folder, the same one with the settings.py. Name it settings.ini and put the following values in it.
[settings] SECRET_KEY=fnokvs7x4)qry7t$!m76yo@e4e2_(1b83czm^@ngt_pe=%%wnhn DB_NAME=comassistdb DB_USER=communityapprole DB_PASSWORD=P@ssw0rd1
I had to add a second % sign to pe=%wnhn to escape it.
We can replace the sensitive data with the config keyword. For instance the secret key can be replaced with
SECRET_KEY=config('SECRET_KEY')
Here are the database settings.
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': config('DB_NAME'), 'USER' : config("DB_USER"), 'PASSWORD': config('DB_PASSWORD'), 'HOST' :'localhost', 'PORT' :'', } }
Make sure you have registered the app, and then try to migrate. If you can migrate the config is working. (You may also have to install psycopg2. To do this just run the command "pip install psycopg2-binary.") When you upload to Github, you place the settings.ini in the git ignore file to keep you sensitive information from being posted in clear text.
No comments:
Post a Comment