ROR Secure

Embed Size (px)

Citation preview

  • 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