Presentation is loading. Please wait.

Presentation is loading. Please wait.

Securing Ruby on Rails CIS 6939 Web Engineering with Ruby on Rails University of North Florida Stephen Jones 8 July 2007.

Similar presentations


Presentation on theme: "Securing Ruby on Rails CIS 6939 Web Engineering with Ruby on Rails University of North Florida Stephen Jones 8 July 2007."— Presentation transcript:

1 Securing Ruby on Rails CIS 6939 Web Engineering with Ruby on Rails University of North Florida Stephen Jones 8 July 2007

2 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, Bulletin Boards, and discussion forums are being used by small and large organizations. Every week hundreds of vulnerabilities are being reported in these web applications, and are being actively exploited. The number of attempted attacks every day for some of the large 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 types of web applications are at risk from web application security defects, ranging from insufficient validation through to application logic errors. Securing Ruby on Rails

3 User Input Regular form fields Hidden form fields Cookies URL Parameters POST data HTTP headers AJAX requests  Scoped Queries Securing Ruby on Rails

4 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 create contact = Contact.new params[:contact] contact.user_id = session[:user_id] contact.save redirect_to contact_url(contact) end Securing Ruby on Rails def show @contact = Contact.find params[:id] end # accessed in URL path like /contacts/42 private def require_signin return false unless session[:user_id] end Record IDs used right in the URL?

5 class 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 :all end 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 Securing Ruby on Rails def update @contact.update_attributes params[:contact] redirect_to contact_url end def destroy @contact.destroy redirect_to contacts_url end private def 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

6 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 class FeedsController < ApplicationController def show @user = User.find_by_token(params[:id]) or raise ActiveRecord::RecordNotFound end Securing Ruby on Rails

7 Mass Assignment contact = current_user.contacts.create params[:contact] contact.update_attributes params[:contact] class UsersController < ApplicationController def edit @user = current_user end def update current_user.update_attributes params[:user] redirect_to edit_user_url end edit.rhtml: user_url, :html => { :method => :put } do |u| %> Login: Password: Securing Ruby on Rails 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_administrator has_many :contacts end class User < ActiveRecord::Base attr_accessible :login, :password has_many :contacts end

8 Form Validation Client-side validation with javascript immediate feedback The data should still be validated on the server side as well. Securing Ruby on Rails

9 SQL Injection passing input directly from user to database malicious users hijack your queries Securing Ruby on Rails # 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='' and password='' or login='bob' and password !=‘ ‘ ) LIMIT 1 #Logs in as any user

10 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] ]) Securing Ruby on Rails

11 Session Fixation cross-site cooking Mitigation use reset_session in your sign-in and sign-out methods # signin def create if u = User.find_by_login_and_password(params[:login], params[:password]) reset_session # create a new sess id, to thwart fixation session[:user_id] = u.id redirect_to home_url else render :action => 'new' end Securing Ruby on Rails

12 Cross-site Scripting (XSS) unescaped user data included in HTML output What’s the problem? Javascript! http://example.com/search?q=%3Cscript%3Ealert('XSS')%3B%3C%2Fscript%3E

13 Securing Ruby on Rails Cross-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 Your search for returned : post) %>: Solution: h helper, also known as html escape. converts &, ", >, and < into &, " >, and < Your search for

14 Securing Ruby on Rails Hashing Passwords MD5 or SHA1 require 'digest/sha1' class User < ActiveRecord::Base attr_accessor :password validates_uniqueness_of :login validates_presence_of :password, :if => :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_password return if password.blank? self.hashed_password = Digest::SHA1.hexdigest(login+password) end def password_required? hashed_password.blank? || !password.blank? end

15 Securing Ruby on Rails Silencing Logs class OrdersController < ApplicationController filter_parameter_logging :cc_number, :cvv, :cc_date #... end

16 Securing Ruby on Rails Advertising Third party widgets

17 Attributation 1. The Ghost In The Browser: Analysis of Web-based Malware Niels Provos, Dean McNamee, Panayiotis Mavrommatis, Ke Wang and Nagendra Modadugu Google, Inc. 2. Ajax on Rails by Scott Raymond 3. Sans Institute Internet Security Attack Targets http://www.sans.org/top20/http://www.sans.org/top20/ 4. Rails Security Mailing List: http://groups.google.com/group/rubyonrails-security Securing Ruby on Rails


Download ppt "Securing Ruby on Rails CIS 6939 Web Engineering with Ruby on Rails University of North Florida Stephen Jones 8 July 2007."

Similar presentations


Ads by Google