2. About Me Blog: http://www.levigross.com/ Twitter:@levigross Email: levi@levigross.com Python for 5 years Django for 2 ½ Computer Security for 8 years Python and Django are amazing!
3. Who is attacking us Bots Malicious SEO Steal user info Hackers ScriptKiddies Hackers ÜberHackers We will bankrupt ourselves in the vain search for absolute security. — Dwight D. Eisenhower
4. Django from a security standpoint Django Rocks! Salted SHA1 Hashes (Yummy) sha1 $ e3164 $ 9595556c4f693158c232f0885d266fe30671ca8a Take that Gawker! Secure session framework Automatic variable escaping XXS SQL Injection CSRF (Cross Site Request Forgery) Protection Protection against Email Header injection Protection against Directory Traversal attacks “If you think technology can solve your security problems, then you don’t understand the problems and you don’t understand the technology”. — Bruce Schneier
5. Web Vulnerabilities Information Disclosure Input Validation Click Jacking Session Hijacking CSRF Passwords Denial of Service 0 days In theory, one can build provably secure systems. In theory, theory can be applied to practice but in practice, it can't. — M. Dacier, Eurecom Institute
7. Attack Surface Admin Site Defaults to /admin Views & URLS Can give someone an intimate view of your application. File Locations REST Use Piston Sentry
8. How to protect yourself Never deploy with the default settings Long URLS are the best (but your not out of the woods) Change the file name/location of user content Validate uploads Remove unneeded software if not chroot
10. Cross Site Scripting Django Protects us by autoescaping output return mark_safe(force_unicode(html). replace('&', '&'). replace('<', '<'). replace('>', '>'). replace(' " ', '"'). replace(" ' ", ''')) |safe/{% autoescape off %} is not Safe
11. Here comes the sleep deprivation My Template Code Secure:<span class={{value}}>{{ value }}</span> Not Secure:<span class="{{value|safe}}">{{value|safe}}</span> Using this value -> " onclick=alert(document.cookie) type=" Secure: <span class=" onclick=alert(document.cookie) type=">" onclick=alert(document.cookie) type="</span> Not Secure:<span class="" onclick=alert(document.cookie) type="">" onclick=alert(document.cookie) type="</span> Oops…
12. How to protect yourself Use the ESAPI (Enterprise Security API) " onclick=alert(document.cookie) type=" '" onclick=alert(document.cookie) type="’ http://code.google.com/p/owasp-esapi-python/ Use Quotes Use Sanitizers lxml html5lib Use Whitelists Use Markdown
13. SQL Injection Python protects us Parameterized queries according to PEP 249 Django’s ORM Protects us parameterized queries Person.objects.filter(first_name__icontains=fname,last_name__icontains=lname) fname = % output -> SELECT "secpre_person"."id", "secpre_person"."first_name", "secpre_person"."last_name" FROM "secpre_person" WHERE ("secpre_person"."first_name" LIKE % % ESCAPE 'apos; AND "secpre_person"."last_name" LIKE %s% ESCAPE 'apos; ) smart_unicode(x).replace("", "").replace("%", "").replace("_", "") NEVER BUILD QUERYIES USING STRING FORMATTING query = 'SELECT * FROM secpre_personWHERE last_name = %s' % lnamePerson.objects.raw(query) UseParameterizedqueries Person.objects.raw('SELECT * FROM secpre_personWHERE last_name = %s', [lname])
14. HTTP Response Splitting New Lines in the HTTP Headers HTTP/1.1 302 Moved Temporarily Date: Wed, 24 Dec 2003 15:26:41 GMT Location: http://10.1.1.1/someview/?lang=foobar Content-Length: 0 HTTP/1.1 200 OK Content-Type: text/html Content-Length: 19 <html>Control</html> Server: Apache Content-Type: text/html This was just found on Reddit last week Kudos to Neal Poole from Matasano Django to the rescue Every HttpResponse object has this code if '' in value or '' in value: raise BadHeaderError("Header values can't contain newlines (got %r)" % (value))
15. CRLF Injection Hijack email forms to:”me@myaddress.comcc:bill.gates@microsoft.comcc:paul.allen@microsoft.com” Django to the rescue if '' in val or '' in val: raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
16. Directory Traversal ../../../../../../../../../etc/passwd Django should never serve static files Your webserver should serve all static files and be locked into the web root directory Never allow users to dictate what happends Django Static Serve isn’t powerless drive, part = os.path.splitdrive(part) head, part = os.path.split(part) if part in (os.curdir, os.pardir): # Strip '.' and '..' in path. continue
17. Click Jacking Use X-FRAME HTTP header X-FRAME-OPTIONS: DENY https://github.com/paulosman/django-xframeoptions Use a Framekiller <script type="text/javascript"> if(top != self) top.location.replace(location); </script> Beware of sites that you visit
18. Session Hijacking FireSheep Cookie info not sent over HTTPS Pass the hash SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True Sessions Never store private data in clear text Never display session data without escaping it
19. Cross Site Request Forgery <imgsrc="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory"> We are logged in so it works Django protects us (unless we are really stupid) HTTP/1.0 200 OK Date: Mon, 17 Jan 2011 21:55:14 GMT Server: WSGIServer/0.1 Python/2.7.1 Expires: Mon, 17 Jan 2011 21:55:14 GMT Vary: Cookie Last-Modified: Mon, 17 Jan 2011 21:55:14 GMT ETag: "4030d6e6a6c31292791e61e8bc58b6e8" Cache-Control: max-age=0 Content-Type: text/html; charset=utf-8 Set-Cookie: csrftoken=9260e87b366dd2be2515bffffec5a746; Max-Age=31449600; Path=/
20. Denial Of Service Everything is vulnerable Impossible to defend against every variant Harden your server Rate limiting Do this on a server level If you need to do this on a view level https://gist.github.com/719502 Fine tune access methods for your views restrict the HTTP method to the appropriate view
21. Passwords Passwords are your biggest nightmare Don’t trust them Make sure that you are using SHA1 Even though it works md5 and crypt shouldn’t be used. crypt should NEVER be used!!! Rate limiting Use Django-axes http://code.google.com/p/django-axes/ Never rely on just a password If you can use 2 factor authentication do it.
22. 0 Day Protection Run for the hills Good security is like a big onion Many layers Bitter Limit your exposure Server monitoring Remember a good programmer looks both ways before crossing a one way street.
23. Security Tips Be wary of updates Update on security releases Beware of 3rd party apps Separate work from play Don’t rely on passwords Fail2Ban Stick with Django Be careful where you stray Scan often Skipfish
Salted hashes make it harder to guess the password by making each password unique. They are immune to rainbow table (pre-generated hashes) attacks.
Don’t try to create your own version of REST. Use something like Django-Piston which has a proven track record. Also never use your object ID’s in urls. If needed use UUID’s
The regular Django auto escape helps in almost every case. However you need to protect yourself in every case. That’s why using the ESAPI is one of the best solutions to the overall problem.
The Django ORM is escaping my LIKE query using the function on the bottom. All other queries are parameterized.
SESSION_COOKIE_HTTPONLY should be set if you don’t want JavaScript to touch your cookie.
Without that cookie you get a 403 if you want to post to that form.
Easy 2 factor auth is sending a SMS to a persons cellphone. If your going to use OAUTH then remember to send everything secure (HTTPS).
Django has a lot of security built in so if you ever replace any part of it make sure it’s secure enough to be on your website.