2. 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
3. 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 %>
7. Cross-Site Scripting in Rails 3
textilize() and simple_format() do not return
safe strings
textilize(‘*bold*‘) #=><strong>bold</strong>
<%= textilize(@product.description) %>
NO <%=raw textilize(@product.description)%>
OK <%=sanitize textilize(@product.description)
%>
7
8. 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
9. Cross-Site Scripting in Rails 3
Know what you‘re doing
Strings aren't magic:
value = sanitize(@product.description)
value.html_safe? #=> true
value.gsub!(/--product_name--/, @product.title)
value.html_safe? #=> true
<%= value %>
9
10. 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
11. Cross-Site Scripting in Rails 3
xml.instruct!
xml.description do
xml << "The description: "
xml << @product.description
end
Use xml.description @product.description to
automatically escape
11
12. Ajax and XSS
No automatic escaping in RJS templates
page.replace_html :notice,
"Updated product #{@product.title}"
12
13. 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 characters
13
14. 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/
loofah
Loofah.fragment(unsafe_html).scrub!(:strip)
14
17. Other changes in Rails 3
config/initializers/session_store.rb
Rails.application.config.session_store
:cookie_store, :key => "_app_name_session"
config/initializers/cookie_verification_secret.rb
Rails.application.config.cookie_secret =
'somereallylongrandomkey'
Don‘t keep it in your SCM
17
18. 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
19. Respond_with in Rails 3
class ProductsController < ApplicationController
respond_to :html, :xml, :json
def index
respond_with(@products = Product.all)
end
end
How to define what attributes to render in XML?
@product.to_xml(:only => [:id])
19
20. 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
21. Bits and pieces
Check what they‘re downloading
File.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