Essential website functions stay available. You can change these choices at any time using Cookie settings in the footer.

Essential functions — always available
Navigation, security, your saved privacy choices, and the enquiry form when you submit it.

Read the Cookie Policy

Guide — cybersecurity

Python and Django Security Best Practices

Use Django’s built-in safeguards deliberately while hardening Python dependencies, settings, data access, and the production deployment path.

2026-10-24 · 10 min

Team discussing a technical audit, representing Python and Django security review

Begin with Django’s production checklist

Run a supported Python and Django release and review the current Django deployment checklist for the version you operate. Execute Django’s deployment checks, but treat them as a starting point rather than proof that the application is secure.

Set DEBUG to false, use an unpredictable secret key stored outside source control, and configure allowed hosts explicitly. Enforce HTTPS at the edge and application layer with a proxy configuration that Django can trust. Set secure session and CSRF cookies, HSTS after validating HTTPS, and appropriate proxy SSL header settings. A wrong proxy trust configuration can let a client influence whether the application believes a request is secure.

Preserve template and request protections

Django templates escape values by default. Limit uses of safe, mark_safe, direct HTML construction, or custom filters that change escaping behaviour. Sanitize intentionally supported rich text and document its allowlist. Add a Content Security Policy as a separate defence-in-depth layer.

Keep CSRF middleware enabled for cookie-authenticated browser actions. Any exemption should have a documented alternate authentication and replay strategy. Validate forms, serializers, query parameters, headers, and uploaded files on the server, including size and content constraints.

Enforce permissions at the object boundary

Authentication does not establish access to every record. Check tenant, ownership, role, and action whenever an object is read or changed. Avoid retrieving an object globally and checking only whether the user is logged in. Scope querysets to the current principal and test cross-account identifiers directly.

Use Django’s password hashing and authentication mechanisms rather than custom password storage. Add rate limits or equivalent controls around login, password reset, invitation, and expensive endpoints. Invalidate sessions appropriately when accounts or privileges change.

Use safe database, file, and process patterns

Prefer the ORM and parameterized query interfaces. Raw SQL, dynamic identifiers, and custom database functions require focused review. Protect against resource exhaustion with pagination, query limits, indexes, timeouts, and asynchronous handling for expensive work.

Treat uploads as untrusted. Generate storage names, restrict sizes and expected formats, keep uploads away from executable paths, and authorize every download. Image or document processing libraries should be current and isolated where practical.

Avoid deserializing untrusted pickle data and do not pass untrusted strings to shells or dynamic code execution. Use argument arrays with subprocesses, narrow process permissions, and destination controls for server-side HTTP requests.

Control Python dependencies and deployment

Pin resolved dependencies and build reproducible artifacts. Scan packages for known vulnerabilities, review package ownership and installation behaviour, and remove unused dependencies. Protect package-registry and source-control accounts with multi-factor authentication.

Run the application under a dedicated, non-root user behind a maintained reverse proxy and production application server. Set request-size, connection, and timeout limits. Separate web and worker privileges when their needs differ. Keep database, cache, queue, and cloud credentials distinct and narrowly scoped.

Centralize logs without collecting secrets or unnecessary personal information. Alert on authentication anomalies, authorization failures, administrative changes, and unusual errors. Test database and uploaded-file restoration together so recovery produces a consistent application state.

Python and Django review checklist

  • Supported Python and Django versions are patched and dependencies are pinned.
  • Production checks pass; debug, hosts, proxy trust, HTTPS, cookies, and HSTS are correct.
  • Template escaping, CSRF, validation, and object-level permissions are tested.
  • Raw SQL, subprocesses, deserialization, uploads, and outbound requests are reviewed.
  • Processes, databases, workers, and cloud services use least-privilege identities.
  • Monitoring, backups, restoration, rollback, and incident ownership are documented.

Need help applying this?

Our team can review your situation and respond with a clear, written answer.

Brands we’ve worked with

  • Morguard
  • Triovest
  • Walmart
  • TELUS
  • Urban Planet
  • Union Burger
  • Halton Healthcare
  • MPAC
  • Reader’s Digest
  • KWE
  • Home Instead
  • FASTSIGNS
  • Sun Life