Safeguard
Security Guides•

Django HTTPS settings in order: redirect, cookies, HSTS

Which Django settings turn on HTTPS properly, in what order, and the proxy mistake that can quietly break CSRF protection. Short and practical.

Safeguard Security Team
3 min read

To run Django properly over HTTPS, redirect HTTP to HTTPS, mark the session and CSRF cookies secure, then add HSTS last and gradually. If you sit behind a reverse proxy, be careful with SECURE_PROXY_SSL_HEADER, because the Django security docs warn that a wrong value can open CSRF problems.

Step 1: get HTTPS working first

Settings cannot fix a site that does not serve a valid certificate. Get TLS working at your load balancer or web server, confirm every page loads over HTTPS, and only then touch Django settings. Turning on HSTS before this point can lock users out.

Step 2: redirect HTTP to HTTPS

SECURE_SSL_REDIRECT = True makes Django redirect HTTP requests to HTTPS. The Django docs note that with a reverse proxy, the web server may be a better place for the redirect. Pick one place and make it consistent, so you do not get redirect loops.

Step 3: the two cookies

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

The first keeps the session cookie off plain HTTP. The second does the same for the CSRF cookie. These two lines are the cheapest hardening you can do.

Step 4: tell Django about your proxy, carefully

If TLS ends at a proxy, Django sees plain HTTP from the proxy and cannot tell the original request was secure. SECURE_PROXY_SSL_HEADER fixes that by trusting a header the proxy sets. The docs say to set it only if you are behind a proxy and to read its warnings first, because misconfiguration can enable CSRF vulnerabilities.

The rule behind the warning: only trust that header if your proxy strips it from incoming client requests and sets it itself. Otherwise any client can claim to be on HTTPS.

Step 5: HSTS, slowly

HSTS tells browsers to use HTTPS for future visits. The relevant settings are:

  • SECURE_HSTS_SECONDS: Turns HSTS on and sets how long browsers remember
  • SECURE_HSTS_INCLUDE_SUBDOMAINS: Extends it to every subdomain
  • SECURE_HSTS_PRELOAD: Allows submission to browser preload lists

Start with a small value for SECURE_HSTS_SECONDS, confirm nothing breaks, then raise it. Include subdomains only after you have checked every subdomain serves HTTPS. Preload submits your domain to browser lists, so treat it as a deliberate decision and check the preload requirements first. You can also set HSTS on the web server instead.

Common mistakes

  • Enabling HSTS with a long lifetime before a subdomain has a certificate.
  • Setting SECURE_PROXY_SSL_HEADER when the proxy does not overwrite the header.
  • Doing the redirect in both Django and the proxy and creating a loop.
  • Forgetting the cookie flags because the redirect "already handles it".

Quick check

Is SECURE_SSL_REDIRECT enough without secure cookies?

No. A first plain HTTP request can still send cookies before the redirect happens, so set both cookie flags.

Should I set SECURE_HSTS_PRELOAD on day one?

Usually not. Roll out HSTS with a short lifetime first, and treat preload as a deliberate step after everything else works.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.