ruby on rails security updated (rails 3) at railswaycon
Post on 14-Jul-2015
21.154 Views
Preview:
TRANSCRIPT
Heiko Webers
CEO of bauland42: Secure and innovative web applications, security code audits:http://www.bauland42.de http://www.werkstatt42.de
Ruby on Rails Security Project: Blog and Book at http://www.rorsecurity.info
Cross-Site Scripting in Rails 3
Before: <%= h @project.name %>@project.name #=> <script>h(@project.name) #=> <script>
After: <%= @project.name %>
Unless you want to allow HTML/JS: <%= raw @project.name %>
Cross-Site Scripting in Rails 3
@project.name.html_safe? #=> false h(@project.name).html_safe? #=> true link_to(...).html_safe? #=> true "<br />".html_safe # => "<br />"
4
Cross-Site Scripting in Rails 3
safe + safe = safe safe.concat(safe) = safe (safe << safe) = safe
safe + unsafe = unsafe...
5
Cross-Site Scripting in Rails 3
String interpolation <%= "#{link_to(@product.title, @product)}
#{link_to(@product.title, @product)}" %> Deliberately unsafe
6
Cross-Site Scripting in Rails 3
textilize() and simple_format() do not return safe stringstextilize(‘*bold*‘) #=><strong>bold</strong>
<%= textilize(@product.description) %> NO <%=raw textilize(@product.description)%> OK <%=sanitize textilize(@product.description)
%>
7
Cross-Site Scripting in Rails 3
Know what you‘re doing <%= auto_link(@product.description) %>
# => unsafe, so escaped <%= raw auto_link(@product.description) %>
# => safe, but may contain HTML sanitize() it
8
Cross-Site Scripting in Rails 3
Know what you‘re doing Strings aren't magic:
value = sanitize(@product.description)value.html_safe? #=> truevalue.gsub!(/--product_name--/, @product.title)value.html_safe? #=> true<%= value %>
9
Cross-Site Scripting in Rails 3
Rails helper are becoming stable now There were problems with content_tag(), tag(),
submit_tag(), ... SafeErb plugin doesn‘t work yet/anymore
10
Cross-Site Scripting in Rails 3
xml.instruct!xml.description do xml << "The description: " xml << @product.descriptionend
Use xml.description @product.description to automatically escape
11
Ajax and XSS
No automatic escaping in RJS templates page.replace_html :notice,
"Updated product #{@product.title}"
12
Sanitization
Don‘t write it on your own:value = self.description.gsub("<script>", "")<scr<script>ipt>
sanitize(), strip_tags(), ... use the HTML::Tokenizer
Based on regular expressions Doesn‘t always render valid HTML Last vulnerability in Rails 2.3.5 regarding non-
printable ascii characters13
Sanitization
Use parsers like Nokogiri or Woodstox (JRuby) Gem sanitize: http://github.com/rgrove/sanitize
Sanitize.clean(unsafe_html) Gem Loofah: http://github.com/flavorjones/
loofahLoofah.fragment(unsafe_html).scrub!(:strip)
14
Sql-Injection in Rails 3
No find() anymore, no :conditions hash, ...But: Product.find(params[:id])
User.order('users.id DESC').limit(20).all NO: Product.where("id = #{params[:id]}") Product.where(["id = ?", params[:id]]) Product.where({:id => params[:id]})
15
Sql-Injection in Rails 3
NO: User.order(params[:order]).all raise "SQLi" unless ["id asc", "id desc"].include?
(params[:order]) Escape it yourself:
Product.order(Product.connection.quote(params[:order])).all
16
Other changes in Rails 3
config/initializers/session_store.rbRails.application.config.session_store :cookie_store, :key => "_app_name_session"
config/initializers/cookie_verification_secret.rbRails.application.config.cookie_secret = 'somereallylongrandomkey'
Don‘t keep it in your SCM
17
Other changes in Rails 3
Keep a value in a signed cookie:cookies.signed[:discount] = "12"
filter_parameter_logging deprecated config.filter_parameters << :password
in config/application.rb
18
Respond_with in Rails 3
class ProductsController < ApplicationController respond_to :html, :xml, :json def index respond_with(@products = Product.all) endend
How to define what attributes to render in XML?@product.to_xml(:only => [:id])
19
Bits and pieces
You can deploy with a SSH key:ssh_options[:keys] = ["/path/to/id_rsa.ppk"]
Secure the admin panel with a client SSL certificate
Remove secrets from your SCM: database.yml, ssh_config.rb
20
Bits and pieces
Check what they‘re downloadingFile.dirname(requested_filename) == expected_directory
/download?file=../config/database.yml validates_format_of :filename,
:with => /^[a-z\.]+$/i hello.txt
<script>alert(1)</script> Use \A and \z
21
Privilege escalation
def update @doc = Doc.find(params[:id]) end
before_filter :load_project before_filter :deny_if_not_full_access before_filter :load_doc
@doc = @project.docs.find(params[:id]) before_filter :deny_if_no_access_to_doc
22
Authorization
def deny_if_no_access_to_doc @doc.may_edit?(current_user) end
def may_edit?(usr) self.creator == usr end
<%= link_to(“Edit“,...) if @doc.may_edit?(current_user) %>
23
top related