Take the 2-minute tour ×

If I create a brand new Rails application (using Rails 3.0.9) and knock up a quick bit of scaffolding as follows:

$ rails new testing
$ rails g scaffold thing name:string

Then app/controllers/application_controller.rb contains a "protect_from_forgery" by default, so it should check the authenticity_token during a POST create. At least, that's my understanding.

Why then, does this line successfully create a new Thing, without supplying the token.

$ curl -F "thing[name]=abc123" http://localhost:3000/things

The log entry says:

Started POST "/things" for at 2011-07-05 08:29:18 +0100
  Processing by ThingsController#create as 
  Parameters: {"thing"=>{"name"=>"abc123"}}
  AREL (0.3ms)  INSERT INTO "things" ("name", "created_at", "updated_at") VALUES  ('abc123', '2011-07-05 07:29:18.484457', '2011-07-05 07:29:18.484457')
Redirected to http://localhost:3000/things/18
Completed 302 Found in 89ms

I can also do this to delete records:

$ curl -X DELETE http://localhost:3000/things/18

The same thing happens in production mode. Doesn't this leave my application open to CSRF?

share|improve this question
Are you authenticating the user based on a session ID? –  polarblau Jul 5 '11 at 10:53
add comment

1 Answer

up vote 1 down vote accepted

If you pass invalid CSRF token or send request without it, Rails will nullify session, so protect_form_forgery is useless if your application could be accessed by everyone. But it will save your application from CSRF attack if you have session-based authentication system.

More info: How does Rails CSRF protection work?

share|improve this answer
So if I want to use http basic for authentication, then protect_from_forgery won't protect me? I seem to remember that in previous versions the token was checked more aggressively. –  SteveP Jul 5 '11 at 14:57
@SteveP: I've tested it and it seems like protect_form_forgery would not protect you when you use HTTP Basic Auth. Because it doesn't make any sense. –  BitOfUniverse Jul 5 '11 at 15:16
What about if I log in (using http basic) and then later browse a remote site containing a form such as: <form method="post" action="mysite...">;. If the token is checked then that won't be a threat. Incidentally, I can get the behaviour I want by adding "verify_authenticity_token" to the create, update and delete methods of the controller. Just surprised that's not the default. –  SteveP Jul 5 '11 at 15:42
add comment

Your Answer


