Tuesday, January 18, 2011

CSRF | Cross Site Request Forgery | Handling in Ruby On Rails

What happens: When the user views a form to create, update, or destroy a resource, the rails app would create a random authenticity_token, store this token in the session, and place it in a hidden field in the form. When the user submits the form, rails would look for the authenticity_token, compare it to the one stored in the session, and if they match the request is allowed to continue.

Why this happens: Since the authenticity token is stored in the session, the client can not know its value. This prevents people from submitting forms to a rails app without viewing the form within that app itself. Imagine that you are using service A, you logged into the service and everything is ok. Now imagine that you went to use service B, and you saw a picture you like, and pressed on the picture to view a larger size of it. Now, if some evil code was there at service B, it might send a request to service A (which you are logged into), and ask to delete your account, by sending a request to http://service%5FA.com/close%5Faccount. This is what is known as CSRF (Cross Site Request Forgery).

If service A is using authenticity tokens, this attack vector is no longer applicable, since the request from service B would not contain the correct authenticity token, and will not be allowed to continue.
Notes: Keep in mind, rails only checks POST, PUT, and DELETE requests. GET request are not checked for authenticity token. Why? because the HTTP specification states that GET requests should NOT create, alter, or destroy resources at the server, and the request should be idempotent (if you run the same command multiple times, you should get the same result every time).

Lessons: Use authenticity_token to protect your POST, PUT, and DELETE requests. Also make sure not to make any GET requests that could potentially modify resources on the server.

Interested in using Java Libraries with Ruby??

Java now holds the lead in many areas of software development, but dynamic languages threaten to bypass it in this inexorable climb. Languages such as Python, Perl, Rexx, Groovy, TCL, and Ruby have been doing yeoman service in specialized domains such as file processing, test automation, software builds, glue code, and Web GUIs for years.Here is the technique to glue them together.

JRuby

JRuby, an open source Ruby interpreter for the JVM, simplifies Ruby-Java integration. You can call Java libraries from Ruby, script Java applications with an embedded interpreter, or even use Ruby libraries from Java. 

Monday, January 17, 2011

Interested in using .NET Libraries with Ruby??

Obsessed with .Net and want to use it as ruby. Here is the solution:-
IronRuby is a Open Source implementation of the Ruby programming language for .NET, heavily relying on Microsoft's Dynamic Language Runtime.

Difference between "and" and "&&"--"or" and "||" ruby operators

One of the subset of Ruby operators are
&&, and, ||, or 
everybody gets confused when to use which operator and what advantage one operator has on another. I came across a very nice article by Avdi on these four operators, just give it a glimpse...

Integerating Rails with Twitter using OAuth

To integerate twitter with your existing rails application follow the steps below:-
  1. Install required Gem as sudo gem install Twitter.
  2. Register your application in read-write mode with Twitter.
  3. Note down the ConsumerToken and ConsumerSecret when application is registered on Twitter.
  4. Refer the attached controller to authorize user on Twitter using OAuth and update the status there.

app/twitters_controller.rb

class TwittersController < ApplicationController
  
  #it is obtained from twitter when your application is registered
  ConsumerToken, ConsumerSecret  = 'consumer token', 'consumersecreat'
  
  before_filter :verify_oauth, :only => [:share_status]
  
  def share_status
    begin
      client.update("Voila! Status set from globallogic")
      flash[:notice] = "Twitter status updated successfully"
    rescue Exception => e 
      flash[:warning] = "Status is duplicate/invalid"
    end
    redirect_to root_path
  end
  
  def finalize
    oauth.authorize_from_request(session['rtoken'], session['rsecret'], params[:oauth_verifier])
    #profile = Twitter::Base.new(oauth).verify_credentials
    session['rtoken'] = session['rsecret'] = nil
    session[:atoken] = oauth.access_token.token
    session[:asecret] = oauth.access_token.secret
    redirect_to session[:redirect_to]
  end
  
  private
    def oauth
      @oauth ||= Twitter::OAuth.new(ConsumerToken, ConsumerSecret, :sign_in => false)
    end


    def client
      oauth.authorize_from_access(session[:atoken], session[:asecret])
      Twitter::Base.new(oauth)
    end
  
    def verify_oauth
      if session[:atoken].blank? or session[:asecret].blank?
        session[:redirect_to] = {:controller => params[:controller], :action => params[:action]}
        oauth.set_callback_url(finalize_twitters_url)


        session['rtoken']  = oauth.request_token.token
        session['rsecret'] = oauth.request_token.secret
    
        redirect_to oauth.request_token.authorize_url
      end
    end
  
end

Accessing session data using session_id

This is the very rare case but some times we need to access the data stored in ActiveRecordStore through session_id(specially when the request is not coming from browser). Here is a way I found and like to share:

@user_id = ActiveRecord::SessionStore::Session.
find_by_session_id('<session_id>').data[:user_id]