Hacking Ruby on Rails at Railswaycon09
-
Upload
heikowebers -
Category
Technology
-
view
7.448 -
download
2
Transcript of Hacking Ruby on Rails at Railswaycon09
Hacking Ruby on Rails
Heiko Webers, bauland42
Heiko Webers
CEO of bauland42: Secure and innovative web applications, security code audits:http://www.bauland42.de
Ruby on Rails Security Project: Blog and Book at http://www.rorsecurity.info
Cross-Site Scripting in Rails 3
Before: <%= h @project.name %> After: <%= @project.name %> Unless you want to allow HTML:
<%= raw @project.name %>
Automatically safe:<%= content_tag(:div, text) + tag(:br) %>
Mark as safe:<%= content_tag(:div, text) + “<br />“.html_safe! %>
Hit list: Mass assignment
User.new(params[:user]) params[:user] #=
{:login => “admin“, :admin => true} attr_accessible :login
Hit list: Privilege escalation
def edit @user = User.find(prams[:id]) end restful-authentication plugin has authorization module
Hit list
filter_parameter_logging :password, :credit_card_no, :bank_account_no
Don‘t deploy/SVN database.yml Enforce TLS during transmission of sensitive
information: credit card numbers, passwords Test security: Authentication, authorization, SQL
Injection, XSS
Hit list
The entire application is only as secure as the weakest link
Update server software frequently: phpMyAdmin, OpenSSL, gems, web server
Review the signup and login process No weak security questions when password forgotten Block account when too many wrong passwords Require to enter the (old) password when changing a password/e-mail address
Hit list
Proactively check the server security with Nessus
Hit list: Cryptography
Don‘t store sensitive information in the clear Use a one-way cryptographic hash function to compare
passwords assert_equal OpenSSL::Digest::Digest.new('SHA1', entered_password), @user.password
Generate an individual SALT value for each user record
Add the SALT to the password string and encrypt it Use only secure ciphers (no DES or MD5)
Hit list: Cryptography
Use symmetric cryptography to encrypt large amounts of data, for example AES, 128 key length
Asymmetric cryptography can be used if another application decrypts the information
Hello admin panel
Admin panel
Admin panel security is even more important Vulnerabilities are harder to exploit, but more destructive I‘ve seen XSS holes in spam reports, user names, ...
Can be used to steal an administrator‘s session Social engineering may help to get access
Hack the e-mail account of an employee to request the admin password
In most admin panels attackers can run completely riot and CRUD everything
Admin panel
Inside the panel Take precautions for the worst case: Introduce different
admin roles or require to enter another password for serious actions
Validate/Filter input and output just as in the main application
Admin panel
Authentication Put the panel to another sub-domain
A stolen admin cookie from www. doesn‘t work in admin. Don‘t authenticate with user name and password from the
main application
Admin panel
Authentication Block the admin account for 15 minutes after 3 unsuccessful
logins Authenticate with something you have, not with something you
know Allow access only from certain IP addresses (check request.remote_ip)
Allow access only from certain machines with client SSL certificates
File uploads
Everything allowed:class Company < ActiveRecord::Base has_attachment :storage => :file_system, :path_prefix => 'public/files'end
File uploads
Allow only images:class Company < ActiveRecord::Base has_attachment :storage => :file_system, :path_prefix => 'public/files', :content_type => :image
validates_as_attachmentend
Now upload logo.html.jpg IE displays the HTML
File Uploads and Apache
Now upload logo.php.jpg Address the file and see the executed PHP
LoadModule php4_module modules/libphp4.soAddType application/x-httpd-php .php
It‘s a common misconception that this will enable the module only for files ending in .php
File Uploads Countermeasures
Store uploaded files outside DocumentRoot directory if you can
Come up with a random/artificial filename if you can Use AV scanners to check the file before allowing
access to it
But how to check for the correct MIME type?
File Uploads MIME Type
Problem: Checking the file name and MIME type provided by the user is not reliable
logo.jpg may still be evil
This file contains a PNG signature: %PNG And a JavaScript comment:
<script>alert('You are vulnerable!');</script>
MIME Type Sniffing
Internet Explorer will sniff the first 256 bytes for its MIME type if it‘s disputed
IE assumes text/html if these strings are found: <html, <head, <body, <plaintext, <pre, <table, <a href, <title, <img src, <script
Only carried out when the file URL is opened directly - not when requested by an image tag
File Uploads Countermeasures
The easy way: Convert uploaded images to JPEG Not allowed? What about other file types?
File Uploads Countermeasures
Validate the file name and MIME type from the client Do the same on the server: shared-mime-info gem
See MIME sniffing countermeasures blog post There may be problems with unknown file types
Attachment_fu: Height and Width must not be NULL for images
Check the first 256 bytes for HTML Use send_file :disposition => 'attachment' if possible
Questions?