Security in Django: A Complete Guide to XSS, CSRF, SQL Injection, Clickjacking, HTTPS, Host Validation, and More

This article provides a comprehensive overview of Django’s built‑in security features. It covers protection against XSS, CSRF, SQL injection, clickjacking, insecure cookies, HTTPS misconfiguration, Host header attacks, and referrer policy concerns. It also explains best practices for securing Django applications.

Django security, XSS protectionCSRF protection, SQL injection prevention, clickjacking, HTTPS, HSTS,ALLOWED_HOSTS, secure cookies, Django middleware

~5 min read • Updated Mar 15, 2026

Introduction

Django is designed with security in mind and includes strong protections against many common web vulnerabilities. This article provides an overview of Django’s security mechanisms and best practices for keeping your application safe.


Always Sanitize User Input

The most important rule in web security is simple: never trust user input. All user‑controlled data must be validated and sanitized before use. Django’s forms framework provides robust tools for validating and cleaning input.


Cross‑Site Scripting (XSS) Protection

XSS attacks occur when malicious scripts are injected into pages viewed by other users. Django’s template system automatically escapes dangerous characters, protecting against most XSS attacks.

Limitations

Template escaping is not perfect. For example:



If var contains malicious JavaScript, it may still execute depending on the browser. Quoting attribute values prevents this issue.

Be cautious when using:

  • safe template tag
  • mark_safe
  • autoescape off
  • Custom template tags with is_safe

Storing raw HTML in the database also increases XSS risk.


Cross‑Site Request Forgery (CSRF) Protection

CSRF attacks trick users into performing actions without their consent. Django includes strong CSRF protection via CsrfViewMiddleware.

How it works

  • Each POST request must include a secret CSRF token.
  • The token is tied to a cookie unique to the user.
  • HTTPS deployments also validate the Referer header.

Avoid disabling CSRF protection unless absolutely necessary.


SQL Injection Protection

SQL injection allows attackers to execute arbitrary SQL commands. Django’s ORM prevents SQL injection by using parameterized queries.

However, when using:

  • raw()
  • RawSQL
  • extra()

you must manually escape user input.


Clickjacking Protection

Clickjacking occurs when a malicious site embeds your site inside a hidden frame. Django prevents this using the X-Frame-Options middleware.

You can configure:

  • DENY
  • SAMEORIGIN
  • Per‑view overrides

This middleware is recommended for all sites unless framing is required.


SSL / HTTPS

HTTPS is essential for protecting data in transit. Without HTTPS, attackers can intercept or modify traffic.

Recommended settings

  • SECURE_SSL_REDIRECT = True
  • SESSION_COOKIE_SECURE = True
  • CSRF_COOKIE_SECURE = True
  • SECURE_HSTS_SECONDS (enable HSTS)
  • SECURE_PROXY_SSL_HEADER (if behind a proxy)

HSTS ensures browsers always use HTTPS for your domain.


Host Header Validation

Fake Host headers can be used for CSRF, cache poisoning, and malicious link generation. Django validates Host headers using the ALLOWED_HOSTS setting.

Do not rely solely on web server configuration. Always set ALLOWED_HOSTS explicitly.

If using X-Forwarded-Host, you must enable:


USE_X_FORWARDED_HOST = True

Referrer Policy

Browsers send the Referer header to indicate where a request originated. Setting a Referrer Policy helps protect user privacy.

Django’s security middleware allows you to configure this header.


Conclusion

Django provides strong, built‑in protections against many common web vulnerabilities. By understanding XSS, CSRF, SQL injection, clickjacking, HTTPS configuration, and Host header validation, you can build secure and resilient web applications. Security is an ongoing process—always validate input, use HTTPS, and keep Django updated.

Cross-Origin Opener Policy (COOP)

The Cross-Origin Opener Policy (COOP) header isolates a top-level browsing context from other documents. When enabled, if a protected page opens a cross-origin popup, the popup’s window.opener property becomes null, preventing direct interaction.

COOP helps defend against cross-origin attacks. For configuration details, refer to Django’s security middleware documentation.


Session Security

Django’s session framework (django.contrib.sessions) has limitations similar to CSRF protection. If untrusted users have access to your subdomains, session security may be weakened.

See the session security section of Django’s documentation for more details.


User-Uploaded Content

Handling user-uploaded files is inherently risky. While Django provides tools for managing uploads, developers must implement additional safeguards.

Key Recommendations

  • Limit upload size at the web server level to prevent DOS attacks
    For example, Apache’s LimitRequestBody directive.
  • Disable handlers like mod_php that might execute uploaded files as code.
  • Beware of disguised files: An HTML file with a valid PNG header can pass Pillow’s validation and later be rendered as HTML, enabling XSS attacks.

Mitigation Strategies

  • Serve uploaded files from a separate top-level domain
    Example: If your site is example.com, serve media from usercontent-example.com. Note: A subdomain like media.example.com is not sufficient.
  • Restrict allowed file extensions
  • Configure your web server to serve only approved file types

Content Security Policy (CSP)

CSP is a browser security mechanism that helps prevent XSS and other injection attacks. Django 6.0 introduces built-in CSP support.

Benefits of CSP

  • Blocks inline scripts and restricts external script loading
  • Controls which external resources (images, fonts, stylesheets) can be loaded
  • Prevents unwanted framing (protects against clickjacking)
  • Supports violation reporting for debugging and monitoring

Limitations and Considerations

  • Avoid excluding routes: Excluding even one path weakens the entire CSP due to same-origin policy interactions.
  • Performance overhead: Nonce generation requires secure randomness per request.
  • Browser compatibility: CSP Level 3 directives may not be fully supported across all browsers.

Additional Security Topics

Django provides strong security features, but secure deployment practices are equally important.

  • Keep Python code outside the web server’s document root
    Prevents accidental exposure or execution.
  • Handle user-uploaded files carefully
  • Protect against brute-force login attempts
    Django does not throttle authentication attempts by default. Use third-party apps or web server modules to limit login attempts.
  • Keep SECRET_KEY (and SECRET_KEY_FALLBACKS) private
  • Restrict access to your database and caching system using firewalls
  • Review the OWASP Top 10 to understand common web vulnerabilities
  • Consult Mozilla’s web security guidelines for additional best practices

Conclusion

Django offers robust security features, but true protection requires thoughtful deployment and careful handling of user-generated content. By implementing COOP, CSP, secure session practices, safe file handling, and following industry best practices, you can significantly strengthen the security of your Django applications.

Written & researched by Dr. Shahin Siami