Prevent CSRF

Posted by Shugo Maeda Sat, 06 Aug 2005 13:13:00 GMT

I could not find any CSRF protection support in Rails 0.13.1. So I did it myself.

At first, I changed ApplicationController and ApplicationHelper.

app/controller/application.rb:

class ApplicationController < ActionController::Base
  private

  def validate_session
    if @params[:session_id_validation] == @session.session_id
      return true
    else
      render(:text => SESSION_VALIDATION_FAILED_HTML,
             :status => "403 Forbidden")
      return false 
    end
  end

  SESSION_VALIDATION_FAILED_HTML = <<EOF
<html>
  <head>
    <title>403 Forbidden</title>
  </head>
  <body>
    <h1>403 Forbidden</h1>
    <p>
      Session validation failed.
    </p>
  </body>
</html>
EOF
end

app/helpers/application_helper.rb:

module ApplicationHelper
  def secure_form_tag(*args)
    return start_form_tag(*args) + "\n" +
      hidden_field_tag("session_id_validation", @session.session_id)
  end
end

Then replaced start_form_tag by secure_form_tag.

app/views/<controller_name>/edit.rhtml:

<h1>Edit</h1>

<%= secure_form_tag :action => 'update', :id => @model_name %>
  <%= render_partial 'form' %>
  <%= submit_tag 'Edit' %>
<%= end_form_tag %>

<%= link_to 'Show', :action => 'show', :id => @model_name %> |
<%= link_to 'Back', :action => 'list' %>

Finally, specified before_filter to each action.

app/controllers/<controllername>controller.rb

class <ControllerName>Controller < ApplicationController
  before_filter :validate_session, :only => [:create, :update, :destroy]

  ...
end

scaffold generates code to destory by GET, so I added a view for confirmation and added a form to destroy by POST.

Leave a comment, View comments, View trackbacks

Your Comments.

Leave your own response

Other posts about this post.

This post has been discussed on the following web sites / blogs. If you wish to trackback to this post please use the following trackback address: http://blog.shugo.net/articles/trackback/5

Spread the word.

Shugo's Blog supports RSS (Real Simple Syndication), and Trackbacks from other blogs.

RSS feed for this post Trackback URI

Your Reply

Comment Form.

Fields denoted with a "*" are required.

You may also like to leave your email or website.