Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Security in Django

Avatar for Florian Apolloner Florian Apolloner
November 05, 2015
49

Security in Django

Avatar for Florian Apolloner

Florian Apolloner

November 05, 2015

Transcript

  1. Who am I ? Django core developer Member of Django's

    security & ops team Part time student, part time worker apollo13 on IRC & Github NOT A SECURITY EXPERT!
  2. We will not talk about … Security would be easier

    without humans in the picture! https://xkcd.com/538/
  3. … or … any other of the attacks against SSL/TLS

    out there (or server misconfigs for that matter) Oh: Update to the latest Python point release But please read and apply: https://cipherli.st/ https://www.ssllabs.com/ssltest/
  4. OWASP (or: How are we doing) Taken from: OWASP Top

    10 2013, CC-BY-SA 3.0 (https://www.owasp.org)
  5. Security in Django • SQL/SMTP/OS injections • Authentication and Session

    management • Cross site scripting (XSS) • Cross site request forgery (CSRF) • Unvalidated redirects and forwards • Security checklist • TODOs
  6. SQL injections Database adapters cursor.execute(), .extra(), .raw() & RawSQL() Exploit

    via: sql = 'select * from auth_user where username=%s' cursor.execute(sql % (username,)) Be safe (same for .extra(), .raw() & RawSQL()): cursor.execute(sql, (username,))
  7. OS/LDAP/SMTP/etc. injections Use Django components instead of rolling your own

    (storage/email) Read 3rd party docs (LDAP/os.Popen) Generally: String interpolation is bad
  8. Repeating myself DO NOT TRUST USER INPUT (EVER) Everything the

    browser sends is user input, including EVERY header and filenames/contenttypes in uploads.
  9. Auth and session management What happens during login? (or: why

    shouldn't I implement it on my own) Authenticate the user Set session_auth_hash Flush/rotate session key Rotate CSRF token Check redirects Set session cookie & redirect
  10. In detail • Authentication: Compare (safely) against stored password and

    update if needed • session_auth_hash: Sign out all other sessions after password change • Change session and CSRF tokens on login to prevent fixation • Check next target to ensure that the user stays on the same site
  11. Password storage/validation Multiple Algorithms ootb (bcrypt/PBKDF2/…) Iterations increased every release

    Upgrade to new algos always possible constant_time_compare Password validators since 1.9 Check length/numeric/common… Enabled only for new projects!
  12. Password reset User requests a password reset link Emailed to

    the user Link can be used once (!) to reset the password /reset/MQ/46h-6965b6f67bcf041e513a/ User Timestamp HMAC of User.pk, password, last login & timestamp
  13. XSS Cross-site scripting Reflected or persistent https://site.com/?search=<b>banana</b> => You searched

    for: banana Often easy and can be very dangerous www.minionland.com
  14. XSS protection Auto escaping HTML only, not context aware Replaces

    < > ' “ & with entities Always use quotes around attributes Javascript requires different escaping var mystr = '{{ value|escapejs }}'; Only for use in strings!
  15. XSS Examples Attack: data = "</script><script>alert('xss');//" Worst case (in a

    script tag): var json = {{ data|dumps|safe }}; A little bit better and visibly broken: var json = {{ data|dumps }}; (Browser dev tools!)
  16. XSS Examples 2 Using Django: var json = JSON.parse('{{ data|escapejs

    }}'); Or simpler: var json = {{ data|json }}; from django-argonauts Do not use inside attributes!
  17. XSS protection 2 Defense in Depth X-XSS-Protection: 1; mode=block No

    inline JS, no event handlers Content-Security-Policy (not yet in Django) No User supplied CSS! Check your (filter) libraries & code, many people just do mark_safe(json.dumps())
  18. CSRF protection Enabled by default Does not cover GET/HEAD/OPTIONS/TRACE Server

    generates random value Put it into form (header for ajax) and cookie Compare values on the server again
  19. CSRF protection 2 Why does it work and why can

    we trust the browser here. (Since you said do not trust headers) Form on evil.com: <form method='post' action='somesite.com'> <input name='csrfmiddlewaretoken' value='?' /> How to get the CSRF token?
  20. CSRF protection 3 Our implementation is “secure” (Even if auditors

    tend to disagree) Changing token via Firebug is NOT a security issue
  21. Unvalidated redirects/forwards Attacker redirects to: /auth/login/?next=http://evil.com After login you are

    on evil.com! django.utils.http.is_safe_url More comments than code → hard to get right
  22. Security checklist ./manage.py check --deploy System check identified 9 issues

    (0 silenced). DEBUG = False, SECRET_KEY is secret Enable SECURE_* settings *_COOKIE_(SECURE|HTTPONLY) = True X_FRAME_OPTIONS = 'DENY'
  23. TODO in Django Implement rate limiting (for login etc) 2FA

    (TOTP & U2F as reference implementations) CSRF improvements (#16859) JSON filter for templates