Building secure Django websites

Three Areas

  • Integrity

    • Internal consistency or lack of corruption in electronic data
  • Confidential

    • To keep data secret that was intended to be secrity
  • Available

    • ability to be used or obtained

How cookies and sessions work

Set-cookie: name: value
Cookie: name=value


session: {
    key: 8f70xxxxa3d9,
    user: Erik

If you can access the session of another user, you can impersonate the other user.

Cross Site Request Forging

Fortunately for us, if you use POST, Django by default has CSRF protection enabled via:

    {% csrf_token %}

XSS Injection

Injecting HTML or JavaScript into things like field data

<p>Injecting issues <script>alert("I'm a JavaScript injection!");</script></p>

Reflected vs. Stored XSS

  • Previous examples are reflected XSS

    • Have to try the user into visiting my link
  • Other possibility is stored XSS

    • Store some data which is later sent back to users, e.g. blog comments

Server side injections

SQL injection

  • No concern, Django ORM prevents injection
  • If you don’t use it, stick to prepared statements

LDAP Injections

  • You can play creative games if you know the LDAP specification


I saw this at NASA HQ before we rolled out my first professional Python application back in 2006.

Shell Injection

  • Always use subprocess

Trusting the Browser

  • The browser is under the user’s control
  • Which means you cannot trust anything that the user is doing

Be careful with ModelForms

Don’t use the exclude Meta attribute in ModelForms!

class Profile(models.Model):
    user = ForeignKey(User)
    phone = models.CharField()
    is_admin = BooleanField() # added later

class ProfileForm(ModelForm):
    model = Profile
    exclude = ('user', )
    {{ form.non_field_errors }}
    Phone: {{ }}

Passwords and SSL

  • Don’t use plaintext passwords
  • Limit the number of attempts (django-axes, django-lockout)
  • If you use logins, use SSL
  • If you use SSL, look at django-secure

Clickjacking and Django

  • Protection in Django 1.4
  • django.middleware.clickjacking
  • etc


  • Run backups
  • If you don’t have backups, who owns your stuff?
  • Test your restores!

Introducing PLY

  • PLY is an implementation of lex and yacc for Python
  • Made by David Beazley
  • Naming conventions and introspection => very “economic” code

Let’s us compile things like:

groups name="XXX" AND NOT groups__name="YYY"
(modified > 1/4/2011 OR NOT state__name="OK") AND groups__name=="XXX"

into django.db.models.Q objects