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

Shiny, Let's Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulnerabilities -- 2015 edition

Shiny, Let's Be Bad Guys: Exploiting and Mitigating the Top 10 Web App Vulnerabilities -- 2015 edition

Slides from the Pycon 2015 presentation of our tutorial that walks through the OWASP Top 10 web application vulnerabilities.

E4c5e3c69566ff80db62a4ab521b6e5a?s=128

Mike Pirnat

April 08, 2015
Tweet

Transcript

  1. Shiny Let’s Be Bad Guys! Exploiting and Mitigating the Top

    1 0 Web App Vulnerabilities Mike Pirnat David Stanek - @mpirnat - @dstanek PyCon 2015
  2. Announcements

  3. Schedule • This session will run 9:00 AM - 12:20

    PM • 20-minute break at ~10:15 AM • Refreshments right outside • Lunch in room 710
  4. Tutorial Feedback • Via the Guidebook app • Look for

    the Tutorial Survey link in the talk details • Be honest! :-)
  5. Volunteering Opportunities • Low-commitment! Fun! • Swag bagging: Thursday 3-6

    PM • Registration Desk: any time • https://us.pycon.org/2015/about/ volunteers/
  6. Shiny Text Let’s Be Bad Guys! Exploiting and Mitigating the

    Top 1 0 Web App Vulnerabilities Mike Pirnat David Stanek - @mpirnat - @dstanek
  7. http://i.qkme.me/3r16r5.jpg

  8. Who here makes web apps?

  9. Who here has vulnerable apps?

  10. Why it Matters • Your users • Your data •

    Your business
  11. OWASP • http://www.owasp.org • Open Web Application Security Project •

    Non-profit focused on improving software security • Documentation and tools to help learn about security and protect your apps
  12. OWASP Top Ten • Based on risk data from 8

    firms • Over 500,000 vulnerabilities, hundreds of orgs, thousands of apps • Selected & prioritized by prevalence data combined with estimates of exploitability, detectability, and impact • Updated in 2013
  13. Today • Background on a type of vulnerability • Exploit

    it! • Discuss prevention • Django & Flask specific advice where possible • Light examples where we have time
  14. Disclaimer

  15. About Django

  16. Setup: 1 Make & activate a virtualenv: # Python 3...

    $ pyvenv badguys # Python 2... $ virtualenv badguys $ cd badguys $ source bin/activate
  17. Setup: 2 Clone our repository: $ git clone https://github.com/ mpirnat/lets-be-bad-guys

    src Or pull the latest changes: $ cd src $ git pull
  18. Setup: 3 Install dependencies: $ cd src $ pip install

    -r requirements.txt
  19. Setup: 4 Start up the app: $ python manage.py runserver

  20. Find a Partner

  21. Injection

  22. Injection Attacks • When an application sends untrusted data to

    an interpreter • Can result in data loss/corruption, lack of accountability, denial of access • Can lead to complete host takeover
  23. Trust No One • External users • Internal users •

    Administrators
  24. Attack Vectors • GET parameters • POST parameters • PATH_INFO

    • Some HTTP headers: Cookie, Host • Uploaded Files
  25. Possible Consequences • Creation of malicious SQL (or other queries)

    • Accessing private files on disk • Arbitrary code execution
  26. Real-World Examples • Sony Playstation Network • Ruby on Rails

    • http://es.pn/Z0jnoi
  27. SQL Injection • Unescaped user input causes the premature end

    of a SQL query and allows a malicious query to be executed... """ select * from users where username='%s'; """ • http://localhost:8000/injection/sql
  28. Accessing Private Files • File system access + unvalidated user

    input allows attackers to navigate the file system • http://localhost:8000/injection/file- access
  29. Arbitrary Code Execution • Unsafe input is dynamically evaluated or

    executed • http://localhost:8000/injection/code- execution
  30. Prevention • Validate ALL user input • Sign cookies, don’t

    accept if signature is bogus/missing • Use ORMs or bind variables when talking to the database • Don’t use eval or exec, beware of pickle, user-supplied YAML, etc.
  31. Django Advice • Make sure data types for your model

    are tight • Use Forms instead of ModelForms for stronger validation • Make new validators as needed for your application • Make sure your URL regexes for dynamic URLs are tight
  32. Django Advice • Use the ORM when you can •

    When you can’t, use extreme caution! • Bind variables • No string concatenation/formatting of anything that came from the client
  33. Without the ORM # If it's a basic select: MyModel.objects.raw("SELECT

    ... WHERE foo = %s", params={'foo': ...}) # If it's more complicated: from django.db import connection cursor = connection.cursor() cursor.execute("UPDATE bar set bar = 1 WHERE foo < %s", [foo]) row = cursor.fetchall()
  34. Flask Advice • Use Flask-WTF to validate form input •

    Use SQLAlchemy • Bind variables if you don’t
  35. Broken Authentication & Session Management

  36. Broken Auth & Session Management • Attacker uses leaks or

    flaws in authentication or session management to impersonate users • Roll-your-own solutions contribute to the difficulty of finding these flaws
  37. Possible Consequences • Compromised user accounts • Compromised administrative accounts

    • Unauthorized use of privileged functionality
  38. Prevention • Hash or encrypt passwords • Don’t let credentials

    be easily overwritten • Don’t put session IDs in URLs • Allow session IDs to timeout/log out • Rotate session IDs after successful login • TLS connections for passwords, session IDs
  39. Django Advice • Use django.contrib.auth • Consider https://github.com/yourlabs/ django-session-security middleware

    for timing out sessions • We’ll talk about transport layer security later on...
  40. Flask Advice • Use flask-security • https://pythonhosted.org/Flask-Security/ • Avoid overuse

    of cookies for storing session state
  41. Cross-Site Scripting (XSS)

  42. XSS Attacks • Cross-Site Scripting (XSS) • The most prevalent

    web app security flaw • App includes user-supplied data in content sent to the browser without properly validating or sanitizing it
  43. XSS Attacks • Stored: injected code permanently stored in database,

    message forum, comment, etc. • Reflected: injected code in live request to server, reflected back in error message or search result • DOM: injected code in browser DOM environment that causes scripts to run in unexpected ways (eg, reading from URL)
  44. Possible Consequences • Execute scripts in a victim’s browser •

    Hijack sessions • Deface sites • Insert hostile content • Redirect users • Hijack browser (install malware)
  45. Most Often Seen... • Places where user-created text is displayed

    to other users (comments, messages) • Form inputs where value is populated with user-supplied data • Script tags where user-supplied data is populated into script variables
  46. XSS in Dynamic URLs • Part of the URL path

    is variable, isn’t validated, and gets included into the page • http://localhost:8000/cross-site- scripting/path-matching/your-path- here
  47. XSS in Query String Parameters • Unvalidated user input from

    a query string parameter is included in the page • http://localhost:8000/cross-site- scripting/query-params?qs=awesome
  48. XSS in Form Fields • The value part of an

    input is prematurely terminated, allowing Javascript to be injected into the element (eg, adding an onclick) • http://localhost:8000/cross-site- scripting/form-field
  49. Can you trust the database?

  50. Prevention • Escape all untrusted data based on the HTML

    context the data will be placed into • Whitelist input validation • Consider auto-sanitization libraries for rich content (eg, OWASP’s AntiSamy) • Update your parents’/in-laws’ browsers!
  51. Django Advice • Be careful with the safe filter, django.utils.safestring,

    etc. • Use form.as_p, form.as_table, form.as_ul when displaying a form in a template • Be careful with your own template tags; django.utils.html.escape is your friend!
  52. django.utils.html cleaned = escape(unsafe_value) cleaned = escapejs(unsafe_value) cleaned = strip_tags(unsafe_value)

    cleaned = remove_tags(unsafe_value, ['script', ...])
  53. Flask Advice • Don’t disable autoescaping • Be very careful

    with anything you bless via Markup objects, the safe filter, or blocks where autoescape is disabled
  54. Insecure Direct Object References

  55. Insecure Direct Object Reference • Expose a reference to an

    internal implementation object without verifying authorization • Attacker changes URL or GET/POST parameters, cookies
  56. Possible Consequences • Compromise of all data that can be

    referenced by the vulnerable parameter • Unless the namespace is sparse, an attacker can easily access all available data of that type
  57. Exercises • Manipulate parameters in the URL to access data

    that doesn’t belong to you • http://localhost:8000/direct-object- references
  58. Prevention • Implement access controls on any direct references to

    restricted resources • Implement per-user or per-session indirect object references • This can be as much about URL design as about access control!
  59. Django + Flask • Lock down views: • Use Django’s

    permissions architecture • Use Flask-Security or Flask-Login • Customize Django queryset for looking up objects that involve user ownership
  60. Custom Queryset # In models.py... class ThingyManager(models.Manager): def for_user(self, user):

    return self.get_query_set().filter(user=user) class Thingy(models.Model): objects = ThingyManager() # In views.py... class ThingyUpdateView(UpdateView): def get_queryset(self): return Thingy.objects.for_user( self.request.user)
  61. Security Misconfiguration

  62. Security Misconfiguration • Insecure application settings • Unpatched flaws •

    Unused pages
  63. Possible Consequences • Unauthorized access to some system data or

    functionality • Potential complete system compromise
  64. Exercises • Demos and discussion • http://localhost:8000/misconfiguration

  65. Prevention • Have a repeatable hardening process • Have a

    process for keeping on top of updates and patches • Architecture that provides secure separation between components • Periodic scans and audits
  66. Django Advice • Don’t run in debug mode in production

    • Keep your SECRET_KEY secret! • Keep Python code out of webserver’s root • Don’t run admin publicly (if you can help it) • Don’t use the built-in admin for normal user admin tasks
  67. Flask Advice • Read http://flask.pocoo.org/docs/ security • Set app.debug =

    False to turn off debugging
  68. Gateway to Social Engineering?

  69. Sensitive Data Exposure

  70. Sensitive Data Exposure • Failure to properly protect credit cards,

    tax ids, authentication credentials, etc. • Sensitive data deserves extra protection such as encryption at rest or in transit, special precautions when exchanged with the browser
  71. Insecure Cryptographic Storage • Not encrypting worthy data • Unsafe

    key generation & storage, failure to rotate keys • Weak algorithms • Weak or unsalted hashes
  72. Insufficient Transport Layer Protection • May not authenticate, encrypt, and

    protect the confidentiality and integrity of sensitive network traffic • May use weak algorithms • May use expired or invalid certificates • May use certificates incorrectly
  73. Possible Consequences • Compromise of all data that should have

    been encrypted • This can be highly sensitive information: credentials, credit cards, personal data, health records, etc.
  74. Possible Consequences • Expose individual users’ data • Account theft

    • Compromise an admin account?! • Poor SSL setup can facilitate phishing and man-in-the-middle attacks
  75. Attack Vectors • Attacker monitors network traffic of your users

    • Maybe in public places (Starbucks, conference wi-fi, etc.) • Maybe back end connections • Maybe inside your network (!!!)
  76. Prevention • Encrypt sensitive data at rest • Encrypt offsite

    backups; manage keys separately • Use strong standard algorithms, strong keys • Hash passwords with strong standard algorithm & use appropriate salt • Protect passwords & keys from unauthorized access
  77. Prevention • Require SSL for all sensitive pages; redirect non-SSL

    requests to SSL • Set the “secure” flag on sensitive cookies • Use only strong SSL algorithms • Ensure your cert is valid, not expired, not revoked, and matches your domain • SSL/encryption on the back end too
  78. Django Advice • Use django.contrib.auth for proper password salting and

    hashing • Use bcrypt; see https://docs.djangoproject.com/en/ 1.8/topics/auth/passwords/ • Require SSL in Apache or Nginx • Require SSL using middleware: • Configure Django SecurityMiddleware–new in Django 1.8! • http://django-secure.readthedocs.org/en/v0.1.2/ • https://github.com/rdegges/django-sslify
  79. Secure Cookies # In your settings.py... SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE

    = True
  80. Flask Advice • Salt passwords using werkzeug.security: • http://flask.pocoo.org/snippets/54/ •

    Require SSL: • https://github.com/kennethreitz/flask-sslify • https://github.com/jacobian/wsgi-sslify • Use bcrypt; see https://pythonhosted.org/ passlib/
  81. Missing Function Level Access Control

  82. Missing Function Level Access Control • Application doesn’t protect its

    functions properly • Misconfiguration • Forgot proper code checks
  83. Attack Vectors • Authorized user changes a URL or parameter

    to a privileged function • Anonymous users could access private functions that aren’t protected
  84. Possible Consequences • Compromised user accounts • Compromised administrative accounts

    • Unauthorized use of privileged functionality
  85. Exercises • Manipulate the URL to access privileged functionality •

    http://localhost:8000/missing-access- control
  86. Prevention • Consider every page; public or private? • If

    authentication is required, make sure that checks are in place • If additional authorization is required, make sure that checks are in place • Deny all by default; explicitly grant access to users or roles
  87. Django + Flask • Lock down views: • Use Django’s

    permissions architecture • Use Flask-Security or Flask-Login • Don’t use Django’s built-in admin for normal user admin tasks
  88. Cross-Site Request Forgery

  89. CSRF Attacks • Cross-Site Request Forgery (CSRF) • Attacker tricks

    victim into submitting forged HTTP requests • Attack succeeds if user is authorized/ authenticated
  90. Attack Vectors • Image tags • Cross-Site Scripting (XSS) •

    Fake buttons • Phishing forms • Other techniques
  91. Possible Consequences • Cause victim to change any data the

    victim is allowed to change • Cause victim to perform any function the victim is authorized to use • Impact varies based on victim’s role • Think of some possibilities...
  92. Real-World Examples • Facebook: http://amolnaik4.blogspot.com/ 2012/08/facebook-csrf-worth- usd-5000.html • Google/Gmail: http://cryptogasm.com/2012/02/does-

    google-understand-csrf/
  93. CSRF via Image • Craft an “image” link that triggers

    some site functionality • http://localhost:8000/csrf/image
  94. What if... <img src="http://example.com/transferFunds?amount=1500& destinationAccount=attackersAcct#" width="0" height="0" />

  95. CSRF via Form Post • Create an innocuous-looking form that

    POSTs to a vulnerable location • http://localhost:8000/csrf/third-party- site
  96. Prevention • Don’t “do” things on a GET • Include

    a unique token in a hidden field (often used in concert with a cookie) • Validate token to make sure the request is from on-site • Avoid putting the token into a query string
  97. Django Advice • Don’t change the built-in settings! • Do

    use the CSRF middleware and template tag in forms • Be VERY CAREFUL about deactivating it (csrf_exempt decorator) • Be careful about APIs (Tastypie, oauth); http://codrspace.com/vote539/csrf- protection-in-django-tastypie/
  98. Flask Advice Various CSRF solutions... • DIY/naïve: http://flask.pocoo.org/snippets/3/ • Flask-WTF:

    http://flask-wtf.readthedocs.org/ en/latest/csrf.html • Flask-SeaSurf: https://flask- seasurf.readthedocs.org/en/latest/ • Flask-csrf: http://sjl.bitbucket.org/flask-csrf/
  99. Using Known Vulnerable Components

  100. Components with Known Vulnerabilities • Libraries, frameworks, and other modules

    almost always run with full privilege • Hard to stay up to date on everything • Do you even know all the components in use, let alone their versions? • Components with known problems can be identified & exploited with automated tools
  101. Attack Vectors • Attacker identifies a weak component through scanning

    or manual analysis • Customize exploit as needed • More difficult the deeper the component is in the application
  102. Possible Consequences • Full range of weaknesses are possible •

    Impact could be minimal, or... • Complete host takeover! • Data compromise!
  103. None
  104. None
  105. None
  106. None
  107. None
  108. Prevention • Don’t use components you don’t write (unrealistic) •

    Keep components up to date • Identify all components and versions • Monitor security of these components
  109. Python Advice • Use pip to find old packages: pip

    list --outdated • Use requires.io to monitor dependencies
  110. Django + Flask • Keep an eye on the mailing

    lists: • https://groups.google.com/group/django- announce • http://flask.pocoo.org/mailinglist • Follow @djangoproject on Twitter
  111. Unvalidated Redirects & Forwards

  112. Redirection Abuse • Attacker tricks user into visiting a URL

    that redirects or forwards the request without validating the redirect location • Users prone to click because the link is to a legitimate site
  113. Possible Consequences • Install malware • Phishing/information disclosure • Bypass

    access controls
  114. External Redirection • Use a redirection URL to redirect to

    an external location • http://localhost:8000/redirects-and- forwards/redirects
  115. Forwards • Manipulate a forward parameter to gain access to

    privileged functionality • http://localhost:8000/redirects-and- forwards/forwards
  116. Prevention • Don’t use redirects or forwards • Don’t involve

    user-supplied data to build the redirect location • Ensure the supplied value is valid and authorized for the user
  117. Django Advice • Use django.utils.http.is_safe_url to check redirect URLs •

    Used by django.contrib.auth internally • Consider wrapping is_safe_url if you have to allow other off-domain URLs
  118. Checking Redirects from django.shortcuts import redirect from django.utils.http import is_safe_url

    def my_view(request): ... url = 'http://www.example.com/foo/bar' if is_safe_url(url, host='www.example.com'): return redirect(url) else: ...
  119. Allowing Multiple Safe Hosts from django.utils.http import is_safe_url def is_whitelisted_url(url,

    hosts): for host in hosts: if is_safe_url(url, host=host): return True return False >>> url = 'http://us.pycon.org' >>> whitelist = ['us.pycon.org', 'pycon.org', ...] >>> is_whitelisted_url(url, whitelist) True
  120. Flask Advice • Redirect back: http://flask.pocoo.org/ snippets/62/ • Redirect back,

    more selectively with whitelist, using cookies for previous URL: http://flask.pocoo.org/snippets/120/ • Can modify these approaches to suit, as with the Django example
  121. Who here has vulnerable apps?

  122. Parting Thoughts

  123. Think Like a Bad Guy

  124. Don’t Stop at Ten

  125. Constant Change

  126. Think Positive

  127. Announcements • Feedback! Via Guidebook • Volunteer! https://us.pycon.org/2015/ about/volunteers/ •

    Lunch! Room 710
  128. Links • http://www.owasp.org • https://www.owasp.org/index.php/ Category:OWASP_Top_Ten_Project • https://docs.djangoproject.com/en/dev/ topics/security/ •

    https://github.com/mpirnat/lets-be-bad-guys
  129. Contact Us Mike Pirnat http://mike.pirnat.com @mpirnat David Stanek http://traceback.org @dstanek