You are on page 1of 23

Security On Rails

David Paluy October 2012

"Ruby is simple in appearance, but is very complex inside, just like our human body." Yukihiro "matz" Matsumoto

Agenda

Session Hijacking CSRF Mass Assignment SQL Injection

Websites are all about the data!

When is a user not a user?

You have no way of knowing who or where the data that hits your application is coming from.

Session Hijacking

Session Hijacking

Sniff the cookie in an insecure network. Most people dont clear out the cookies after working at a public terminal Cross-Site Scripting (XSS) CSS Injection Header Injection

config.force_ssl = true

If you have http assets on an https page, the users browser will display a mixed-content warning in the browser bar. Rails does most of the work for you, but if you have any hard-coded http:// internal-links or images, make sure you change them.

Session Expiry
class Session < ActiveRecord::Base def self.sweep(time = 1.hour) if time.is_a?(String) time = time.split.inject { |count, unit| count.to_i.send(unit) } end delete_all "updated_at < '#{time.ago.to_s(:db)}' OR created_at < '#{2.days.ago.to_s(:db)}'" end end

Provide the user with a log-out button in the web application, and make it prominent.

XSS Countermeasures
strip_tags("some<<b>script>alert('hello')<</b>/script>") RESULT: some<script>alert(hello)</script> <%= h post.text %> <%= sanitize @article.body %> view SanitizeHelper

CSS Injection

<div style="background:url('javascript:alert(1)')">

alert(eval('document.body.inne' + 'rHTML'));

Header Injection
redirect_to params[:referer]
http://www.yourapplication.com/controller/action? referer=http://www.malicious.tld

Make sure you do it yourself when you build other header fields with user input.

Session Storage
config.action_dispatch.session = { :key } => '_app_session', :secret => '0dkfj3927dkc7djdh36rkckdfzsg...'

Cross-Site Request Forgery (CSRF)

Most Rails applications use cookie-based sessions

CSRF Countermeasures
Be RESTful
Use GET if:

The interaction is more like a question (i.e., it is a safe operation such as a query, read operation, or lookup).

Use POST if:

The interaction is more like an order, or The interaction changes the state of the resource in a way that the user would perceive (e.g., a subscription to a service), or The user is held accountable for the results of the interaction.
protect_from_forgery :secret => "123456789012345678901234567890..."

Mass Assignment

attr_accessible :name attr_accessible :is_admin, :as => :admin

Mass Assignment

SQL Injection

Project.where("name = '#{params[:name]}'")
SELECT * FROM projects WHERE name = '' OR 1'

User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'")


SELECT * FROM users WHERE login = '' OR '1'='1' AND password = '' OR '2'>'1' LIMIT 1

SQL Injection Countermeasures

Model.where("login = ? AND password = ?", entered_user_name, entered_password).first Model.where(:login => entered_user_name, :password => entered_password).first

Tools

Brakeman - A static analysis security vulnerability scanner for Ruby on Rails applications RoRSecurity explore Rails security Techniques to Secure your Website with RoR

Summary

The security landscape shifts and it is important to keep up to date, because missing a new vulnerability can be catastrophic.

You might also like