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 -- CodeMash 2017 edition

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

Slides from the CodeMash 2017 presentation of my tutorial that walks through the OWASP Top 10 web application vulnerabilities and discusses strategies to mitigate them.


Mike Pirnat

January 11, 2017


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

    1 0 Web App Vulnerabilities Mike Pirnat - @mpirnat CodeMash 2017 Setup: https://github.com/mpirnat/lets-be-bad-guys
  2. Announcements • This session will run 1:00 PM – 5:00

    PM • We’ll break midway through • Snacks & beverages available • Feedback via EventsXD mobile app • Slides linked from github repo Setup: https://github.com/mpirnat/lets-be-bad-guys
  3. Shiny Let’s Be Bad Guys! Exploiting and Mitigating the Top

    1 0 Web App Vulnerabilities Mike Pirnat - @mpirnat CodeMash 2017 Setup: https://github.com/mpirnat/lets-be-bad-guys
  4. Who here makes web apps? Setup: https://github.com/mpirnat/lets-be-bad-guys

  5. Who here has vulnerable apps? Setup: https://github.com/mpirnat/lets-be-bad-guys

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

    Your business Setup: https://github.com/mpirnat/lets-be-bad-guys
  7. 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 Setup: https://github.com/mpirnat/lets-be-bad-guys
  8. OWASP Top Ten • Based on risk data from 8

    security 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 (refresh coming in 2017) Setup: https://github.com/mpirnat/lets-be-bad-guys
  9. Today • Background on a type of vulnerability • Exploit

    it! • Discuss prevention • Django & Flask specific advice where possible • Light examples where we have time Setup: https://github.com/mpirnat/lets-be-bad-guys
  10. Disclaimer Setup: https://github.com/mpirnat/lets-be-bad-guys

  11. About Django Setup: https://github.com/mpirnat/lets-be-bad-guys

  12. About Flask Setup: https://github.com/mpirnat/lets-be-bad-guys

  13. Setup: 1 Make & activate a virtualenv: Setup: https://github.com/mpirnat/lets-be-bad-guys #

    Python 3... $ pyvenv badguys # Python 2... $ virtualenv badguys $ cd badguys $ source bin/activate # Python 3... > pyvenv.py badguys # Python 2... > virtualenv badguys > cd badguys > Scripts/activate.bat
  14. Setup: 2 Clone the repository: $ git clone https://github.com/ mpirnat/lets-be-bad-guys

    src Or pull the latest changes: $ cd src $ git pull Setup: https://github.com/mpirnat/lets-be-bad-guys
  15. Setup: 3 Install dependencies: $ cd src $ pip install

    -r requirements.txt > cd src > pip.exe install -r requirements.txt Setup: https://github.com/mpirnat/lets-be-bad-guys
  16. Setup: 4 Start up the app: $ python manage.py runserver

    Setup: https://github.com/mpirnat/lets-be-bad-guys
  17. Find a Partner Setup: https://github.com/mpirnat/lets-be-bad-guys

  18. Injection

  19. 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
  20. Who can you trust?

  21. Trust No One • External users • Internal users •

  22. Attack Vectors • GET parameters • POST parameters • PATH_INFO

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

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

    • HBGary • MySQL • Many, many others…
  25. 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'; """ • Use 2 dashes to start a SQL comment: -- • http://localhost:8000/injection/sql
  26. Accessing Private Files • File system access + unvalidated user

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

    executed • http://localhost:8000/injection/code- execution
  28. 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.
  29. Django Advice • Make sure data types for your model

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

    When you can’t, use extreme caution! • Use bind variables/parameters • No string concatenation/formatting of anything that came from the client
  31. 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()
  32. Flask Advice • Use Flask-WTF to validate form input •

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

  34. 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
  35. Possible Consequences • Compromised user accounts • Compromised administrative accounts

    • Unauthorized use of privileged functionality
  36. 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
  37. Django Advice • Use django.contrib.auth • Consider http://django-session- security.readthedocs.io/ middleware

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

    Avoid overuse of cookies for storing session state
  39. Cross-Site Scripting (XSS)

  40. 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
  41. 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)
  42. Possible Consequences • Execute scripts in a victim’s browser •

    Hijack sessions • Deface sites • Insert hostile content • Redirect users • Hijack browser (install malware)
  43. 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
  44. Real-World Example • ESPN had a page that exposed unsanitized

    content from the URL • Able to replace the content of the page • Used bit.ly to make an official-looking short URL! • http://es.pn/Z0jnoi
  45. XSS in Dynamic URLs • Part of the URL path

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

    a query string parameter is included in the page: http://example.com/?search={$TEXT} • http://localhost:8000/cross-site- scripting/query-params?qs=awesome
  47. XSS in Form Fields • The value part of an

    input is prematurely terminated, allowing Javascript to be injected into or adjacent to the element: <input … value="{$TEXT}"> • http://localhost:8000/cross-site- scripting/form-field
  48. Can you trust the database?

  49. 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!
  50. Prevention • Use X-XSS-Prevention header to configure browser XSS sanitization

    behavior • Use X-Frame-Options header to control whether and how a page can be loaded within a frame • Use Content-Security-Policy header to specify where a page can load resources from (requires careful tuning)
  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, 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. Text This Really Happens! • Patreon compromised via exposed Werkzeug

    Debugger • https://labs.detectify.com/2015/10/02/ how-patreon-got-hacked-publicly- exposed-werkzeug-debugger/
  66. None
  67. None
  68. None
  69. 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
  70. 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 • Don’t use the built-in admin for normal user admin tasks
  71. Flask Advice • Read http://flask.pocoo.org/docs/ security • Set app.debug =

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

  73. Sensitive Data Exposure

  74. 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
  75. Insecure Cryptographic Storage • Not encrypting worthy data • Unsafe

    key generation & storage, failure to rotate keys • Weak algorithms • Weak or unsalted hashes
  76. 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
  77. 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.
  78. Possible Consequences • Expose individual users’ data • Account theft

    • Compromise an admin account?! • Poor SSL setup can facilitate phishing and man-in-the-middle attacks
  79. 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 (!!!)
  80. http://cdn.ttgtmedia.com/digitalguide/images/Misc/WiresharkSS3_lg.png

  81. http://echeng.com/journal/images/misc/firesheep.png

  82. 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
  83. 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
  84. Prevention •Use HTTP Strict Transport Security (HSTS) header to protect

    against downgrade attacks and cookie hijacking •Consider setting Public Key Pinning (HPKP) header to reduce impersonation by attackers with mis-issued or fraudulent certificates
  85. Django Advice • Use django.contrib.auth for proper password salting and

    hashing • Use bcrypt or Argon2; see https:// docs.djangoproject.com/en/1.10/topics/auth/ passwords/ • Require SSL in Apache or Nginx • Require SSL using middleware: • Configure Django SecurityMiddleware–introduced in Django 1.8! • https://docs.djangoproject.com/en/1.10/ref/middleware/ • https://github.com/rdegges/django-sslify
  86. Secure Cookies # In your settings.py... SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE

    = True
  87. 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 Passlib to do bcrypt or Argon2: • https://passlib.readthedocs.io/en/stable/
  88. Missing Function Level Access Control

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

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

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

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

    http://localhost:8000/missing-access- control
  93. 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
  94. 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
  95. Cross-Site Request Forgery

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

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

    Fake buttons • Phishing forms • Other techniques
  98. 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...
  99. Real-World Examples • Facebook: http://amolnaik4.blogspot.com/ 2012/08/facebook-csrf-worth- usd-5000.html • Google/Gmail: http://cryptogasm.com/2012/02/does-

  100. What if... http://example.com/transferFunds?amount=…&destinationAccount=…

  101. What if... <img src="http://example.com/transferFunds?amount=1500& destinationAccount=attackersAcct#" width="0" height="0" />

  102. CSRF via Image • Craft an “image” link that triggers

    some site functionality • http://localhost:8000/csrf/image
  103. CSRF via Form Post • Create an innocuous-looking form that

    POSTs to a vulnerable location • http://localhost:8000/csrf/third-party- site
  104. 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
  105. 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/
  106. 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/
  107. Using Known Vulnerable Components

  108. 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
  109. 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
  110. Possible Consequences • Full range of weaknesses are possible •

    Impact could be minimal, or... • Complete host takeover! • Data compromise!
  111. None
  112. None
  113. None
  114. None
  115. None
  116. 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
  117. Python Advice • Use pip to find old packages: pip

    list --outdated • Use requires.io to monitor dependencies
  118. 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
  119. Unvalidated Redirects & Forwards

  120. 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
  121. Possible Consequences • Install malware • Phishing/information disclosure • Bypass

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

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

    privileged functionality • http://localhost:8000/redirects-and- forwards/forwards
  124. 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
  125. 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
  126. 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: ...
  127. 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
  128. 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
  129. Who here has vulnerable apps?

  130. Who is ready to do something about it?

  131. Parting Thoughts

  132. Think Like a Bad Guy

  133. Don’t Stop at Ten

  134. Constant Change

  135. Think Positive

  136. Further Exploration • http://www.owasp.org • https://www.owasp.org/index.php/OWASP_Top_Ten_Project • https://www.owasp.org/index.php/OWASP_Secure_Headers_Project • https://www.smashingmagazine.com/2016/09/content-security-

    policy-your-future-best-friend/ • https://docs.djangoproject.com/en/dev/topics/security/ • http://flask.pocoo.org/docs/security • OSCON 2016 & PyCon 2016: Security on a Shoestring • https://www.fullstackpython.com/web-application-security.html • https://github.com/mpirnat/lets-be-bad-guys
  137. Contact Me Mike Pirnat http://mike.pirnat.com @mpirnat Tutorial feedback: EventsXD mobile