Download - ROR Secure
-
7/30/2019 ROR Secure
1/16
Securing Ruby on Rails
Sanjay Kumar Sharma
HMRITM, Delhi
-
7/30/2019 ROR Secure
2/16
Securing Ruby on Rails
SANS Top-20 Internet Security Attack Targets (2006 Annual Update)Top of the list for the Cross-platform Applications category is:
C1 Web Applications
C1.1 Description
Applications such as Content Management Systems (CMS), Wikis, Portals, BulletinBoards, and discussion forums are being used by small and large organizations. Every
week hundreds of vulnerabilities are being reported in these web applications, and arebeing actively exploited. The number of attempted attacks every day for some of thelarge web hosting farms range from hundreds of thousands to even millions.
All web frameworks (PHP, .NET, J2EE, Ruby on Rails, ColdFusion, Perl, etc) and all typesof web applications are at risk from web application security defects, ranging frominsufficient validation through to application logic errors.
-
7/30/2019 ROR Secure
3/16
Securing Ruby on Rails
User Input
Regular form fields
Hidden form fields
Cookies
URL Parameters
POST data
HTTP headers
AJAX requests
Scoped Queries
-
7/30/2019 ROR Secure
4/16
Securing Ruby on Rails
class User< ActiveRecord::Base
has_many :contacts
end
class Contact < ActiveRecord::Base
belongs_to :user
end
class ContactsController< ApplicationController
before_filter :require_signin
def new
@contact = Contact.new
end
def createcontact = Contact.new params[:contact]
contact.user_id = session[:user_id]
contact.save
redirect_to contact_url(contact)
end
def show
@contact = Contact.find params[:id]
end
# accessed in URL path like/contacts/42
private
def require_signinreturn false unless session[:user_id]
end
end
Record IDs used right in the URL?
-
7/30/2019 ROR Secure
5/16
Securing Ruby on Railsclass ContactsController< ApplicationController
# gives us a @current_user object
before_filter :require_signin
# safely looks up the contact
before_filter :find_contact, :except => [ :index, :new,:create ]
def index
@contacts = @current_user.contacts.find :allend
def new
@contact = @current_user.contacts.new
end
def create
@current_user.contacts.create params[:contact]
redirect_to contacts_url
end
def show
end
def edit
end
def update
@contact.update_attributes params[:contact]
redirect_to contact_url
end
def destroy
@contact.destroy
redirect_to contacts_url
end
privatedef require_signin
@current_user = User.find session[:user_id]
redirect_to(home_url) and return false
unless@current_user
end
def find_contact
@contact = @current_user.contacts.find.params[:id]
end
end
-
7/30/2019 ROR Secure
6/16
Securing Ruby on Rails
Record IDs in URLs verified? (HTTP authentication) Is the ID guessable?How about a token?
class User< ActiveRecord::Base
def before_create
token = Digest::SHA1.hexdigest("#{id}#{rand.to_s}")[0..15]
write_attribute 'token', token
end
end
class FeedsController< ApplicationController
def show
@user = User.find_by_token(params[:id]) or
raise ActiveRecord::RecordNotFoundend
end
-
7/30/2019 ROR Secure
7/16
Securing Ruby on RailsMass Assignment
contact = current_user.contacts.create params[:contact]
contact.update_attributes params[:contact]
class UsersController< ApplicationController
def edit
@user = current_user
enddef update
current_user.update_attributes params[:user]
redirect_to edit_user_url
end
end
edit.rhtml:
user_url, :html =>
{ :method => :put } do |u| %>
Login:
Password:
require 'net/http'
http = Net::HTTP.new 'localhost', 3000
http.post "/users/1", 'user[is_administrator]=1&_method=put',
{ 'Content-Type' => 'application/x-www-form-urlencoded' }
class User < ActiveRecord::Base
attr_protected :is_administratorhas_many :contacts
end
class User < ActiveRecord::Base
attr_accessible :login, :password
has_many :contactsend
-
7/30/2019 ROR Secure
8/16
Securing Ruby on Rails
Form Validation
Client-side validation with javascript
immediate feedback
The data should still be validated on the serverside as well.
-
7/30/2019 ROR Secure
9/16
Securing Ruby on Rails
SQL Injectionpassing input directly from user to database
malicious users hijack your queries
# unsafe
User.find(:first, :conditions => "login = '#{params[:login]}' AND
password = '#{params[:password]}'")
SELECT * FROM users WHERE (login='alice' and password='secret') LIMIT 1
' or login='bob' and password !=
SELECT * FROM users WHERE (login='' andpassword='' or login='bob' and password != ) LIMIT 1 #Logs in as any user
-
7/30/2019 ROR Secure
10/16
Securing Ruby on Rails
SQL Injection
# safe (pass a hash to :conditions)
User.find(:first, :conditions => { :login => params[:login],
:password => params[:password] })
# safe (shorter form)
User.find(:first, :conditions =>
[ "login = ? AND password = ?", params[:login], params[:password] ])
-
7/30/2019 ROR Secure
11/16
Securing Ruby on RailsSession Fixation
cross-site cooking
Mitigationuse reset_session in your sign-in and sign-out methods
# signin
def createif u = User.find_by_login_and_password(params[:login],
params[:password])reset_session # create a new sess id, to thwart fixationsession[:user_id] = u.id
redirect_to home_url
elserender :action => 'new'
endend
-
7/30/2019 ROR Secure
12/16
Securing Ruby on Rails
Cross-site Scripting (XSS)
unescaped user data included in HTML output
Whats the problem? Javascript!
http://example.com/search?q=%3Cscript%3Ealert('XSS')%3B%3C%2Fscript%3E
-
7/30/2019 ROR Secure
13/16
Securing Ruby on RailsCross-site Scripting (XSS)#unsafe
:get %>
class SearchController < ApplicationController
def index
@q = params[:q]
@posts = Post.find :all,
:conditions => ["body like :query",
{ :query => params[:q]}]
end
end
Your search for
returned :
post) %>:
Solution: h helper, also known as html
escape.
converts &, ", >, and < into &, "
>, and :password_required?
validates_confirmation_of :password, :if => :password_required?before_save :hash_password
# Authenticates a user by login/password. Returns the user or nil.
def self.authenticate login, password
find_by_login_and_hashed_password(login,
Digest::SHA1.hexdigest(login+password))
end
protected
def hash_passwordreturn if password.blank?
self.hashed_password = Digest::SHA1.hexdigest(login+password)
end
def password_required?
hashed_password.blank? || !password.blank?
end
end
-
7/30/2019 ROR Secure
15/16
Securing Ruby on Rails
Silencing Logs
class OrdersController < ApplicationController
filter_parameter_logging :cc_number, :cvv, :cc_date
# ...
end
-
7/30/2019 ROR Secure
16/16
Securing Ruby on Rails
Advertising
Third party widgets