Python vs the OWASP Top 10

Python vs the OWASP Top 10

Given at HackerSchool.

2f5463832ccb768ccb4a1ca3607c27ef?s=128

Jacob Kaplan-Moss

April 24, 2013
Tweet

Transcript

  1. 1.

    Building Secure Web Apps: Python versus the OWASP Top 10

    Jacob Kaplan-Moss jacob@jacobian.org
  2. 3.
  3. 4.
  4. 5.
  5. 8.

    The OWASP Top 10 1. Injection 2. Broken authentication and

    session management 3. XSS 4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects https://www.owasp.org/index.php/Top_10_2013
  6. 11.

    db = psycopg2.connect() @app.route("/transactions/<user>") def show_transactions(user): c = db.cursor() query

    = "SELECT * FROM transactions WHERE user = '%s'" % username c.execute(query) return flask.render_template('txns.html', transactions=c.fetchall())
  7. 12.
  8. 16.

    GET  /activity/jacob SELECT  *  FROM  activity  WHERE  user  =  'jacob'

    GET  /activity/%27+or+1+%3D+1 SELECT  *  FROM  activity  WHERE  user  =  ''  or  1  =  1
  9. 17.

    GET  /activity/jacob SELECT  *  FROM  activity  WHERE  user  =  'jacob'

    GET  /activity/%27+or+1+%3D+1 SELECT  *  FROM  activity  WHERE  user  =  ''  or  1  =  1 GET  /activity/%27%3B+DELETE+FROM+transactions%3B
  10. 18.

    GET  /activity/jacob SELECT  *  FROM  activity  WHERE  user  =  'jacob'

    GET  /activity/%27+or+1+%3D+1 SELECT  *  FROM  activity  WHERE  user  =  ''  or  1  =  1 GET  /activity/%27%3B+DELETE+FROM+transactions%3B SELECT  *  FROM  activity  WHERE  user  =  '';  DELETE  FROM  activity;
  11. 19.

    Preventing SQLi ‣ Use a database abstraction layer or ORM.

    ‣ Flask: SQLAlchemy ‣ Django: django.db.models ‣ If you must write raw SQL by hand, always use bind parameters: ‣ Good: cursor.execute(query, params) ‣ Bad: cursor.execute(query % params)
  12. 21.

    Vulnerabilities in sessions/auth ‣ Insecure credential storage ‣ Weak account

    management functions (e.g. password recovery) ‣ Poor session security (stealing, forging, fixation, poisoning, etc.)
  13. 24.

    Session security ‣ Use your framework’s session’s APIs; don’t reinvent

    the wheel. ‣ Flask: ‣ Django: django.contrib.sessions ‣ Don’t store data in cookies directly. ‣ Watch your SECRET_KEY! ‣ Always consider session data insecure. Even if it’s stored in the database, it make have been set via a poisoned session.
  14. 27.
  15. 32.

    ‣ Use a template that automatically escapes HTML. ‣ No

    matter how smart you think you are, don’t turn it off! Preventing XSS
  16. 34.
  17. 42.

    class JobApplication(DeclarativeBase) __tablename__ = 'jobapps' id = Column(Integer, primary_key=True) ...

    @app.route("/jobs/application/<id>") def job_application(id): a = JobApplication.query.filter(JobApplication.id == id) return flask.render_template('application.html', application=a)
  18. 43.

    Dear  Jacob  -­‐ Thanks  for  applying  to  work  at  Initech!

     If  you  need  to   make  changes  to  your  job  application,  you  can  do  so  at:        http://initech.com/jobs/application/6749 Good  luck, A.  Drone Director,  Human  Resources
  19. 44.

    class JobApplication(DeclarativeBase) __tablename__ = 'jobapps' id = Column(Integer, primary_key=True) slug

    = Column(String(100)) ... @app.route("/jobs/application/<slug>") def job_application(id): a = JobApplication.query.filter(JobApplication.slug == slug) return flask.render_template('application.html', application=a)
  20. 45.

    Dear  Jacob  -­‐ Thanks  for  applying  to  work  at  Initech!

     If  you  need  to  make   changes  to  your  job  application,  you  can  do  so  at:        http://example.com/jobs/application/jacobkaplanmoss-­‐2013 Good  luck, A.  Drone Director,  Human  Resources
  21. 47.

    No silver bullet ‣ Read the docs: ‣ Flask: http://flask.pocoo.org/docs/security/

    ‣ Django: http://django.me/security ‣ Have a deployment checklist: ‣ Django: http://django-secure.rtfd.org/ ‣ Don’t forget to turn debug mode off! ‣ Flask: app.debug = False ‣ Django: settings.py → DEBUG = False
  22. 49.

    This  is  a  reminder,  sent  out  once  a  month,  about

     your list.example.com  mailing  list  memberships.    It  includes  your subscription  info  and  how  to  use  it  to  change  it  or  unsubscribe   from  a  list. ... Passwords  for  jacob@jacobian.org: List                                                            Password -­‐-­‐-­‐-­‐                                                            -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ mylist@list.example.com                      hunter2 otherlist@list.example.com                2hunter
  23. 50.

    Password storage ‣ Use bcrypt. ‣ Flask: http://pythonhosted.org/passlib/ ‣ Django:

    http://django.me/bcrypt ‣ (PBKDF2 is an acceptable substitute, but use bcrypt anyway.) ‣ Properly hashed passwords are hard — but not impossible — to break. So keep them safe, and consider implementing password security rules.
  24. 53.

    from flask.ext.login import login_required, current_user @app.route("/jobs/application/<id>") @login_required def job_application(id): a

    = JobApplication.query.filter(JobApplication.id == id, JobApplication.applicant == current_user) return flask.render_template('application.html', application=a)
  25. 54.

    ‣ Treat access control holistically, not piecemeal. ‣ Flask: https://flask-login.rtfd.org/

    ‣ Django: django.contrib.auth ‣ Don’t rely on security through obscurity. Handling access control
  26. 61.

    ‣ Don’t allow GET requests to have side effects. ‣

    Protect POST requests with a CSRF token ‣ Flask: http://sjl.bitbucket.org/flask-csrf/ ‣ Flask: http://pythonhosted.org/Flask-WTF/ ‣ Django: (built in) ‣ Protect your SECRET_KEY! Preventing CSRF
  27. 63.

    $  pip  list  -­‐-­‐outdated Django  (Current:  1.5  Latest:  1.5.1) django-­‐contact-­‐form

     (Current:  0.3  Latest:  0.3.1) django-­‐secure  (Current:  0.1.2  Latest:  1.0) Fabric  (Current:  1.4.2  Latest:  1.6.0) psycopg2  (Current:  2.4.6  Latest:  2.5) Pygments  (Current:  1.5  Latest:  1.6) raven  (Current:  1.4.6  Latest:  3.3.3) simplejson  (Current:  2.5.2  Latest:  3.1.3) Sphinx  (Current:  1.1.3  Latest:  1.2b1) ssh  (Current:  1.7.14  Latest:  1.8.0) Unipath  (Current:  0.2.1  Latest:  1.0)
  28. 64.

    ‣ [this is hard] ‣ Update dependencies often. ‣ A

    good test suite helps! ‣ Follow relevant mailing lists ‣ Flask: http://flask.pocoo.org/mailinglist/ ‣ Django: https://groups.google.com/group/django-announce ‣ https://bundlescout.com/ (non-free) Staying up-to-date
  29. 66.
  30. 68.

    Dear  Jacob, You  can  reset  your  password  by  following  this

     link:  http://good.com/password/reset/a02be53ccf9245 Your  friends  at  good.com.
  31. 70.

    Dear  Jacob, You  can  reset  your  password  by  following  this

     link:  http://evil.com/password/reset/a02be53ccf9245 Your  friends  at  good.com.
  32. 71.

    ‣ Whitelisting seems to be the only solid approach. ‣

    Django: ALLOWED_HOSTS ‣ Be very cautious when issuing redirects! ‣ Flask: flask.redirect is unsafe. ‣ Django: django.shortcuts.redirect is unsafe. Validating redirects/forwards
  33. 72.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  34. 73.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  35. 74.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  36. 75.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  37. 76.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  38. 77.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  39. 78.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  40. 79.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  41. 80.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  42. 81.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django
  43. 82.

    1. Injection 2. Broken authentication and session management 3. XSS

    4. Insecure direct object references 5. Security misconfiguration 6. Sensitive data exposure 7. Missing function-level access control 8. CSRF 9. Components with known vulnerabilities 10. Unvalidated redirects The Top 10 vs Flask/Django