Django web security checklist before deployment
You already know web security is important to keep hackers and cyber thieves from accessing sensitive information. So, in this post, we are going to check Django security vulnerabilities and how to fix them.

You already know web security is important to keep hackers and cyber thieves from accessing sensitive information. So, in this post, we are going to check Django security vulnerabilities and how to fix them.
Deployment Checklist
First thing first, check your security vulnerabilities by the following command:
manage.py check --deploy
You can see some descriptions which provide information about your Django web application vulnerabilities. Try to google these security issues and fix them before production.
The Mozilla Observatory
If you already deployed your application then use Observatory by Mozilla site to scan the security status of your site. The site also includes third-party scanners which test other security aspects of your site.
Here is an example of a scan:

Cross-site request forgery (CSRF) protection
In a web application, the webforms take input from the user and send them to server-side components to process them. The server-side components generally expose the service as a POST
, PUT
, DELETE
method for accepting the data over HTTP
. Django has built-in security against most forms of CSRF
threats, as long as you have allowed and used it if necessary.
As stated in the documentation, be very careful when marking views with the csrf_exempt
decorator, unless it is absolutely necessary.
If someone has access (through a man-in-the-middle attack or XSS) to your csrftoken cookie, then this is a vulnerability.
The CSRF protection cannot protect against man-in-the-middle
attacks, so use HTTPS
with HTTP
Strict Transport Security.
Once you’ve set up HTTPS
, add these lines in your settings.py
CSRF_COOKIE_SECURE = True #to avoid transmitting the CSRF cookie over HTTP accidentally.
SESSION_COOKIE_SECURE = True #to avoid transmitting the session cookie over HTTP accidentally.
Cross-site Scripting (XSS)
Cross-site Scripting (XSS) allows an attacker to inject a script into the content of a website or app. When a user visits the infected page the script will execute in the victim’s browser. This allows attackers to steal private information like cookies, account information, etc.
X-XSS-Protection: 1; mode=block
enables XSS filtering. Rather than sanitizing the page, the browser will prevent rendering of the page if an attack is detected.
To enable it in Django, make sure django.middleware.security.SecurityMiddleware
is present in the middleware's list and add the following lines in your settings.py
:
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
Django Admin Security
One of the most important things is to make Django administration secure. Before you deploy your application you must change the admin/
path to something only you know. Otherwise, anyone can access administration simply by testing default URLs.
#urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls) # change admin something different
You can create a fake admin login page using django-admin-honeypot and it will notify you if someone tries to attempt unauthorized access.
SSL Redirect
Add the following line to your settings.py
to force Django to redirect all non-HTTPS requests to HTTPS.
SECURE_SSL_REDIRECT = True
Content Security Policy (CSP)
If your Django application is large, contains a lot of third-party code, and has a lot of inline scripts and styles scattered all over the project, then you should add CSP to your site.
For more information about CSP visit An Introduction to Content Security Policy
Django does not have a built-in method for creating a CSP header, so you can install Mozilla’s django-csp module and use your browser's console to track the security violations in your code.
Once you installed django-csp
, add the following lines to your settings.py
# Content Security Policy
CSP_DEFAULT_SRC = ("'none'", )
CSP_STYLE_SRC = ("'self'", )
CSP_SCRIPT_SRC = ("'self'", )
CSP_IMG_SRC = ("'self'", )
CSP_FONT_SRC = ("'self'", )
So, all inline scripts and styles will not be allowed anymore. All scripts and styles must be loaded from a resource. You can add ‘unsafe-inline’ to your script and style CSP headers, however, it negates the whole policy.
It's really important to clean your code from all these inline styles and scripts. However, some external resources such as Google Tag Manager or Google Analytics should be allowed in your CSP policy. To achieve that update your code like this:
#Content Security Policy
CSP_DEFAULT_SRC = ("'none'", )
CSP_STYLE_SRC = ("'self'", "fonts.googleapis.com", "'sha256-/3kWSXHts8LrwfemLzY9W0tOv5I4eLIhrf0pT8cU0WI='")
CSP_SCRIPT_SRC = ("'self'", "ajax.googleapis.com", "www.googletagmanager.com", "www.google-analytics.com")
CSP_IMG_SRC = ("'self'", "data:", "www.googletagmanager.com", "www.google-analytics.com")
CSP_FONT_SRC = ("'self'", "fonts.gstatic.com")
CSP_CONNECT_SRC = ("'self'", )
CSP_OBJECT_SRC = ("'none'", )
CSP_BASE_URI = ("'none'", )
CSP_FRAME_ANCESTORS = ("'none'", )
CSP_FORM_ACTION = ("'self'", )
CSP_INCLUDE_NONCE_IN = ('script-src',)
For more information take a look django-csp documentation.
Note that this configuration depends on which external resources you are using so please first read the documentation and then apply changes to your site.
HTTP Strict Transport Security
When this policy is set, browsers will refuse to connect to your site for the given time period if you’re not properly serving HTTPS resources, or if your certificate expires.
Add the following lines to your settings.py
:
SECURE_HSTS_SECONDS = 86400 # 1 day
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
Support 🌏
If you feel like you unlocked new skills, please share them with your friends and subscribe to the youtube channel to not miss any valuable information.