Django Security

Django Security

May 16, 2023 | permanent

tags
Django, Security

Tools or Services to check security of a website #

While development #

python manage.py check --deploy

After deployment #

Top 5 Security Check Tools 13 Scan tools for website vulnerability The services mentioned below are included in the above references

Selected #

  1. https://observatory.mozilla.org/
  2. https://sitecheck.sucuri.net/

Additional #

  1. https://quttera.com/detailed_report

Things that were done to get the security grade to A+, using Observatory #

Grade history #

Security Areas #

X-XSS-Protection #

0 X-XSS-Protection header set to “1; mode=block”

X-Frame-Options #

+5 X-Frame-Options (XFO) implemented via the CSP frame-ancestors directive

X-Content-Type-Options #

Subresource Integrity #

Used django-sri package to add integrity hashes to script and link tags.

Referrer Policy #

Redirection #

HTTP Strict Transport Security #

HTTP Public Key Pinning #

Cross-origin Resource Sharing #

Cookies #

Content Security Policy (CSP) #

DigitalOcean’s tutorial on this subject.'

  • Nonce or Hash to selectively allow inline JavaScript

    django-csp can be used to manage nonce or hashes

    • How to activate nonce controlled CSP?

      ref

      # in settings.py
      CSP_INCLUDE_NONCE_IN = ['script-src']
      MIDDLEWARE_CLASSES = (
          #...
          'csp.middleware.CSPMiddleware',
          #...
      )
      
      <script nonce="{{request.csp_nonce}}">
              var hello="world";
      </script>
      
  • inline javascripts of Google tag manager or linked or anyother inline JavaScript

    ref

    <script nonce="{{request.csp_nonce}}">
        window.dataLayer = window.dataLayer || [];
    
        function gtag() {
            dataLayer.push(arguments);
        }
        gtag('js', new Date());
        gtag('config', "{{settings.site_settings.SocialMedia.google_tag_id}}");
    </script>
    

Other helpful resources #

DigitalOcean’s How To Harden the Security of Your Production Django Project #

Use django-environ #

Django settings settings configs to enhance security #

import os
from .base import *
import environ

env = environ.Env()
environ.Env.read_env()

DEBUG = False

ALLOWED_HOSTS = ['your_domain', 'www.your_domain']

DATABASES = {
    'default': {
        'ENGINE': env('SQL_ENGINE', default='django.db.backends.sqlite3'),
        'NAME': env('SQL_DATABASE', default=os.path.join(BASE_DIR, 'db.sqlite3')),
        'USER': env('SQL_USER', default='user'),
        'PASSWORD': env('SQL_PASSWORD', default='password'),
        'HOST': env('SQL_HOST', default='localhost'),
        'PORT': env('SQL_PORT', default=''),
    }
}

SECURE_SSL_REDIRECT = True

SESSION_COOKIE_SECURE = True

CSRF_COOKIE_SECURE = True

SECURE_BROWSER_XSS_FILTER = True
  • ALLOWED_HOSTS

    ALLOWED_HOSTS is a list of strings that represent the host/domain names that your project can serve. This is a security measure to prevent an attacker from poisoning caches and DNS. Find more details about ALLOWED_HOSTS in the Django documentation.

  • SECURE_SSL_REDIRECT

    SECURE_SSL_REDIRECT redirects all HTTP requests to HTTPS (unless exempt). This means your project will always try to use an encrypted connection. You will need to have SSL configured on your server for this to work. Note that if you have Nginx or Apache configured to do this already, this setting will be redundant.

  • SESSION_COOKIE_SECURE

    SESSION_COOKIE_SECURE tells the browser that cookies can only be handled over HTTPS. This means cookies your project produces for activities, such as logins, will only work over an encrypted connection.

  • CSRF_COOKIE_SECURE

    CSRF_COOKIE_SECURE is the same as SESSION_COOKIE_SECURE but applies to your CSRF token. CSRF tokens protect against cross-site request forgery. Django CSRF protection does this by ensuring any forms submitted (for logins, signups, and so on) to your project were created by your project and not a third party.

  • SECURE_BROWSER_XSS_FILTER

    SECURE_BROWSER_XSS_FILTER sets the X-XSS-Protection: 1; mode=block header on all responses that do not already have it. This ensures third parties cannot inject scripts into your project. For example, if a user stores a script in your database using a public field, when that script is retrieved and displayed to other users it will not run.

    • Note

      Settings This option was not injecting the X-XSS-Protection: 1; mode=block in Wagtail 5.0, 4.2 version2, I had to a customer middleware to enable this:

      # middleware.py
      class XSSProtectionMiddleware:
          """
          Add X-XSS-Protection header to response.
          Setting SECURE_BROWSER_XSS_FILTER = True
          in settings.py to enable XSS protection was
          not working, created this middlware to
          add the header custom.
          """
      
          def __init__(self, get_response):
              self.get_response = get_response
      
          def __call__(self, request):
              response = self.get_response(request)
              response["X-XSS-Protection"] = "1; mode=block"
              return response
      
      # settings
      
      MIDDLEWARE = [
          "app.middleware.XSSProtectionMiddleware",
      ]
      
  • Additional settings

    The following settings are for supporting HTTP Strict Transport Security (HSTS)—this means that your entire site must use SSL at all times.

    • SECURE_HSTS_SECONDS

      SECURE_HSTS_SECONDS is the amount of time in seconds HSTS is set for. If you set this for an hour (in seconds), every time you visit a web page on your website, it tells your browser that for the next hour HTTPS is the only way you can visit the site. If during that hour you visit an insecure part of your website, the browser will show an error and the insecure page will be inaccessible.

    • SECURE_HSTS_PRELOAD

      SECURE_HSTS_PRELOAD only works if SECURE_HSTS_SECONDS is set. This header instructs the browser to preload your site. This means that your website will be added to a hard-coded list, which is implemented in popular browsers, like Firefox and Chrome. This requires that your website is always encrypted. It is important to be careful with this header. If at anytime you decide not to use encryption for your project, it can take weeks to be manually removed from the HSTS preload list.

    • SECURE_HSTS_INCLUDE_SUBDOMAINS

      SECURE_HSTS_INCLUDE_SUBDOMAINS applies the HSTS header to all subdomains. Enabling this header means that both your_domain and unsecure.your_domain will require encryption, even if unsecure.your_domain is not related to this Django project.

How to score A+ for Security Headers in Django #

https://adamj.eu/tech/2019/04/10/how-to-score-a+-for-security-headers-on-your-django-website/


Links to this note

Go to random page

Previous Next