Secure Your Django Application

Samiddha
5 min readJul 14, 2023

--

Thumbnail

When deploying the django application for production you must set DEBUG=False in settings.py. Because when DEBUG=True, it shows full tracebacks in the browser when an error is occurred and hence it will leak lots of information about your project: excerpts of your source code, local variables, settings, libraries used, etc.

2. Store Confidential Values in the Environment:

Django uses the string-value assigned to the variable SECRET_KEY for several security purposes, like creating a hash for users’ passwords. If anybody gains access of your source code (e.g. by gaining access of your GitHub account), the attacker may get the user’s original password with the help of the value of the SECRET_KEY. So it is crucial to hide the value of the SECRET_KEY or other confidential variables (like DATABASE_URL, API KEY etc). To do that you can store these values in a local environment. And access the values in your code without reveling the data.

Python provides several packages to work with environment variables. In this tutorial we will use django-environ and python-decouple to fetch data value from the environment.

Step 1: Install django-environ and python-decouple -

pip install django-environ python-decouple

Step 2: Create .env file in Project’s Root-

Create a file (name it to .env) at the root of your project’s directory, i.e. where the manage.py file is located. And store the confidential values in that file with a unique variable name; like VARIABLE_NAME=value. And don’t forget to include the .env in .gitignore file, so that the file will; not upload to your GitHub, since the file contains confidential values and we don’t want to reveal these values.

For example, the contents of the .env file can be:

SECRET_KEY=rt^jkj*yuyy-@jkjkj?8767
API_KEY=sd.87869@jyuy:ioi
DATABASE_URL=postgres://myusername:mypassword@databasename/

Step 3: Now Import the Values in Your Code -

Add the below code in your settings.py

from decouple import config
import environ

env = environ.Env() # To load the .env file from project's root

# We have stored the value of the SECRET_KEY in the .env file in a varable named SECRET_KEY,
# So we will fetch the value from .env using congig function -
# config(VARIABLE_NAME_USED_IN_.env, cast=type_of_the_value)
SECRET_KEY = config("SECRET_KEY", cast=str)

Now, since your GitHub repository doesn’t have .env file, so if anybody able to read your code, the person can’t know the value of the SECRET_KEY.

3. Add ALLOWED_HOSTS:

You must add a list of domains, so that the django application can only access from this allowed origin. For example, if the domain of your site is example.com, so add ALLOWED_HOSTS=[“example.com”] into the settings.py.

For further information check the official docs.

4. Add The Configurations to Prevent Cross-Site Request Forgery (CSRF):

Add the following configurations in the settings.py.

Let the domain of your website is example.com.

# Strict: Allowed on first party requests only. No cross-domain shenanigans
# Lax: Allowed on third party requests from safe top-level navigation (like, links or GET)
# None: Allowed on all first party and third party requests. Must also use the 'Secure' cookie attribute

CSRF_COOKIE_DOMAIN = 'example.com' #The domain to be used when setting the CSRF cookie. If set . before the domain name, then it also allow for subdomain.
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_NAME = '__Secure-csrftoken'
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_COOKIE_SECURE = True # browser trigger the cookie as safe, and only be send by secure connection.
CSRF_USE_SESSIONS = True

For further information check the official docs.

5. Secure the Session Cookies of Your Site:

Add the following configurations in the settings.py.

Let the domain of your website is example.com.

SESSION_COOKIE_DOMAIN = 'example.com'  # The domain to use for session cookies. 
SESSION_COOKIE_HTTPONLY = True # session cookies can only be access by https request.
SESSION_COOKIE_NAME = '__Secure-sessionid'
SESSION_COOKIE_SAMESITE = 'Strict'
SESSION_COOKIE_SECURE = True # browser trigger the session cookie as safe, and only be send by secure connection.
SESSION_SAVE_EVERY_REQUEST = True

For further information check the official docs.

6. Add The Configurations to Increase The Securities:

Add the following configurations in the settings.py.

SECURE_BROWSER_XSS_FILTER = True  # prevent rom xss attack. if true, filter all malicious files, scripts will be filtered.
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_CROSS_ORIGIN_OPENER_POLICY = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_SECONDS = 1 * 365 * 24 * 60 * 60 # 365 days in second
SECURE_REFERRER_POLICY = 'same-origin'
SECURE_SSL_REDIRECT = True

For further information check the official docs.

7. Add Cross-Origin Resource Sharing (CORS) headers to responses:

For security purposes, it is a good practice to disable CORS on your site. Enabling CORS is dangerous since it allows other sites to make cross-origin requests to your site.

To add CORS headers to your site, use the package django-cors-headers.

To learn more about CORS read this resource.

8. Protect Your Site from Clickjacking Attack:

Clickjacking attack occurs when a malicious site tricks a user into clicking on a concealed element of another site which they have loaded in a hidden frame or iframe.

Read the official docs of Django to know how to prevent clickjacking attacks.

9. Add Content Security Policy (CSP) to Your Site:

To add CSP to your site use this package django-csp.

To know what is CSP read this resource.

10. Prevent Your Site from DoS Attacks:

DoS is a type of attack, in which the attacker sends too much traffic/request to a server and the server can’t handle this flood of traffic due to limited memory and resources, hence the server will be crashed. To prevent this attack you must restrict the users’ request. For example, you can restrict that the users can only send only 1000 requests per hour to your site.

To limit the requests you can use the package Django Ratelimit.

11. Filtering Email Error Reports:

When DEBG is False Django sends the server errors with full traceback to the ADMINS. For security reasons, the error reports sent to the Admins’ email must not contain sensitive information, because if anybody gets access of the admin’s email, the person can gain that sensitive information.

Read the official docs to know how to filter sensitive information.

Additional Tips:

To check the securities and vulnerabilities of your site you can use the following online tools -

  1. Mozilla Observatory
  2. ImmuniWeb — Free Security Tests
  3. Arachni — Web Application Security Scanner Framework
  4. SiteCheck
  5. SiteGuarding — Website Scanner
  6. Qualys SSL Labs
  7. Website Scanner Online — Find Site Vulnerabilities Fast
  8. SQL Injection Scanner Online
  9. XSS Scanner — Online Scan for Cross-site Scripting Vulnerabilities
  10. Automated SQLi Exploiter Online
  11. Sniper — Automatic exploitation tool for high-risk vulnerabilities
  12. URL Fuzzer — online hidden file & directory finder
  13. Website Scanner: Vulnerability Scan, SEO Spam & Blacklist Check
  14. ScamAdviser.com — Check a website for risk

Thanks for following these procedures. Always secure your sites.

--

--