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

Security is Broken: Understanding Common Vulner...

Security is Broken: Understanding Common Vulnerabilities

Mountain West Ruby Conference

Eileen M. Uchitelle

March 21, 2016
Tweet

More Decks by Eileen M. Uchitelle

Other Decks in Technology

Transcript

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

    eileencodes.com " @eileencodes # @eileencodes ! speakerdeck.com/eileencodes
  2. • Impossible to test for all possible vulnerabilities • Hackers

    are always one step ahead How is security broken?
  3. • 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?
  4. vs.

  5. • Failed to enforce web standards • Failed to implement

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

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

    a definition of security • Too few people understand the vulnerabilities How did we get here?
  8. <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="[email protected]" 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>
  9. <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="[email protected]" 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>
  10. <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="[email protected]" 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
  11. <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="[email protected]" 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
  12. <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="[email protected]" 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
  13. <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="[email protected]" 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
  14. 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
  15. 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
  16. • 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?
  17. • 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?
  18. XSS

  19. <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 %>
  20. <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 %>
  21. <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
  22. <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
  23. • Don’t HTML escape user-provided data • Sanitize user-provided data

    • Validate user-provided data How to mitigate XSS?
  24. 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
  25. 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
  26. 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
  27. XXE

  28. <!-- 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>
  29. <!-- 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
  30. <!-- 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>
  31. 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
  32. 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
  33. 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
  34. • Don’t parse XML • Don’t use parsers that allow

    entity replacement (LibXML) How to mitigate XXE?
  35. • Don’t parse XML • Don’t use parsers that allow

    entity replacement (LibXML) • Whitelist known entities How to mitigate XXE?
  36. EILEEN M UCHITELLE Security, Performance, & Infrastructure at Basecamp !

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