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

Python vs the OWASP Top 10

Python vs the OWASP Top 10

Given at HackerSchool.

Jacob Kaplan-Moss

April 24, 2013
Tweet

More Decks by Jacob Kaplan-Moss

Other Decks in Technology

Transcript

  1. 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
  2. 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())
  3. GET  /activity/jacob SELECT  *  FROM  activity  WHERE  user  =  'jacob'

    GET  /activity/%27+or+1+%3D+1 SELECT  *  FROM  activity  WHERE  user  =  ''  or  1  =  1
  4. 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
  5. 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;
  6. 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)
  7. Vulnerabilities in sessions/auth ‣ Insecure credential storage ‣ Weak account

    management functions (e.g. password recovery) ‣ Poor session security (stealing, forging, fixation, poisoning, etc.)
  8. 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.
  9. ‣ Use a template that automatically escapes HTML. ‣ No

    matter how smart you think you are, don’t turn it off! Preventing XSS
  10. 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)
  11. 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
  12. 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)
  13. 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
  14. 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
  15. 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  [email protected]: List                                                            Password -­‐-­‐-­‐-­‐                                                            -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐ [email protected]                      hunter2 [email protected]                2hunter
  16. 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.
  17. 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)
  18. ‣ 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
  19. ‣ 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
  20. $  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)
  21. ‣ [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
  22. Dear  Jacob, You  can  reset  your  password  by  following  this

     link:  http://good.com/password/reset/a02be53ccf9245 Your  friends  at  good.com.
  23. Dear  Jacob, You  can  reset  your  password  by  following  this

     link:  http://evil.com/password/reset/a02be53ccf9245 Your  friends  at  good.com.
  24. ‣ 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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. 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. 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