<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Shugo's Blog comments on Prevent CSRF</title>
    <link>http://blog.shugo.net/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Shugo's Blog comments</description>
    <item>
      <title>"Prevent CSRF" by shugo</title>
      <description>&lt;p&gt;I could not find any CSRF protection support in Rails 0.13.1.
So I did it myself.&lt;/p&gt;

&lt;p&gt;At first, I changed &lt;code&gt;ApplicationController&lt;/code&gt; and &lt;code&gt;ApplicationHelper&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;app/controller/application.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::Base
  private

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

  SESSION_VALIDATION_FAILED_HTML = &amp;lt;&amp;lt;EOF
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;403 Forbidden&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;403 Forbidden&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;
      Session validation failed.
    &amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
EOF
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;app/helpers/application_helper.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module ApplicationHelper
  def secure_form_tag(*args)
    return start_form_tag(*args) + "\n" +
      hidden_field_tag("session_id_validation", @session.session_id)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then replaced &lt;code&gt;start_form_tag&lt;/code&gt; by &lt;code&gt;secure_form_tag&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;app/views/&amp;lt;controller_name&amp;gt;/edit.rhtml:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Edit&amp;lt;/h1&amp;gt;

&amp;lt;%= secure_form_tag :action =&amp;gt; 'update', :id =&amp;gt; @model_name %&amp;gt;
  &amp;lt;%= render_partial 'form' %&amp;gt;
  &amp;lt;%= submit_tag 'Edit' %&amp;gt;
&amp;lt;%= end_form_tag %&amp;gt;

&amp;lt;%= link_to 'Show', :action =&amp;gt; 'show', :id =&amp;gt; @model_name %&amp;gt; |
&amp;lt;%= link_to 'Back', :action =&amp;gt; 'list' %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, specified before_filter to each action.&lt;/p&gt;

&lt;p&gt;app/controllers/&amp;lt;controller&lt;em&gt;name&amp;gt;&lt;/em&gt;controller.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class &amp;lt;ControllerName&amp;gt;Controller &amp;lt; ApplicationController
  before_filter :validate_session, :only =&amp;gt; [:create, :update, :destroy]

  ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;scaffold generates code to destory by GET, so I added a view for confirmation
and added a form to destroy by POST. &lt;/p&gt;

</description>
      <pubDate>Sat,  6 Aug 2005 22:13:00 JST</pubDate>
      <guid>&lt;a href="/articles/2005/08/06/prevent-csrf"&gt;Prevent CSRF&lt;/a&gt;</guid>
      <link>&lt;a href="/articles/2005/08/06/prevent-csrf"&gt;Prevent CSRF&lt;/a&gt;</link>
    </item>
  </channel>
</rss>

