如果我创建一个全新的 Rails 应用程序(使用 Rails 3.0.9)并快速搭建一些脚手架,如下所示:
$ rails new testing
$ rails g scaffold thing name:string
然后 app/controllers/application_controller.rb 默认包含一个“protect_from_forgery”,因此它应该在 POST 创建期间检查 authenticity_token。至少,这是我的理解。
那么,为什么这一行在没有提供 token 的情况下成功创建了一个新事物。
$ curl -F "thing[name]=abc123" http://localhost:3000/things
日志条目说:
Started POST "/things" for 127.0.0.1 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
我也可以这样做来删除记录:
$ curl -X DELETE http://localhost:3000/things/18
同样的事情发生在生产模式。这不会让我的申请对 CSRF 开放吗?
最佳答案
如果您传递无效的 CSRF token 或在没有它的情况下发送请求,Rails 将使 session 无效,因此如果每个人都可以访问您的应用程序,protect_form_forgery
将毫无用处。
但如果您有基于 session 的身份验证系统,它将使您的应用程序免受 CSRF 攻击。
更多信息:How does Rails CSRF protection work?
https://stackoverflow.com/questions/6579445/