How can you use the Rails AuthenticityToken framework to explicitly protect a GET action

Rails AuthenticityToken automatically protects POST / PUT / DELETE requests from CSRF attacks. But I have another use case.

I show a video on my site that I do not want to embed on other sites. How it works, my flash player sends a request to a signed URL from my CDN, which expires in a few seconds. Until now, the user had to register to watch the video, so this was authentication. However, now I want any visitor to the site to be able to watch video without resolving the requested URL from another site (for example, if he embedded our player on his site).

My first thought went to the AuthenticityToken, as it seems to be that exact semantics ... all I have to do is connect it to the GET request. Any ideas?

+4
source share
2 answers

Rails is stubborn because he believes that all GET requests should be idempotent. Does this mean that Rails, of course, does not check authentication tokens for GET requests, even verified_queries? gives each get a pass.

def verified_request? !protect_against_forgery? || request.method == :get || !verifiable_request_format? || form_authenticity_token == params[request_forgery_protection_token] end 

So we have to write our own logic. We can use the form_authenticity token. All this creates a random string and caches it in the session:

 def form_authenticity_token session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32) end 

Therefore, we can make a before filter that checks the equality of the url parameter for the session token. Thus, ensuring that only bonafide visitors can view videos.

Controller:

 class CDNController < ActionController::Base # You probably only want to verify the show action before_filter :verify_request, :only => 'show' # Regular controller actionsโ€ฆ protected def verify_request # Correct HTTP response code is 403 forbidden, not 404 not found. render(:status => 403) unless form_authenticity_token == params[:token] end end 

View:

 <%= video_path(:token => form_authenticity_token) %> 
+9
source

To enable the authentication token in the url:

 <%= video_path(:token => form_authenticity_token) %> 

In your CDN controller, you can verify the authentication token is correct using the before_filter parameter:

 def verify_token render_404 unless form_authenticity_token == params[:token] end def render_404 render :file => "#{RAILS_ROOT}/public/404.html", :status => 404 end 
+1
source

All Articles