protect_from_forgery不保护PUT / DELETE请求

我用
rails new demo
制作了一个演示应用程序,然后生成了一个带有
rails generate scaffold User name:string email:string
的脚手架用户控制器。脚手架代码有
ApplicationController
protect_from_forgery
UserController
也是
ApplicationController
。 我运行webrick,添加一个用户,很酷。真实性令牌的工作方式与/ on上的POST一致。 然而,仍然使用Rails 3.0.5我能够做到:
niedakh@twettek-laptop:~$ telnet 10.0.0.4 3000
PUT /users/3 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 39

user[name]=vvvvv&user[email]=shiaus.pl
并且在不给出令牌的情况下修改用户3:
Started PUT "/users/3" for 10.0.0.4 at 2011-04-02 14:51:24 +0200
  Processing by UsersController#update as HTML
  Parameters: {"user"=>{"name"=>"vvvvv", "email"=>"shiaus.plr"}, "id"=>"3"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
', "updated_at" = '2011-04-02 12:51:24.437267' WHERE "users"."id" = 3s.pl
Redirected to http://10.0.0.4:3000/users/3
Completed 302 Found in 92ms
我也可以用DELETE做同样的事情:
DELETE /users/3 HTTP/1.1
这给了我:
Started DELETE "/users/3" for 10.0.0.4 at 2011-04-02 15:43:30 +0200
  Processing by UsersController#destroy as HTML
  Parameters: {"id"=>"3"}
  SQL (0.7ms)   SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
  AREL (0.5ms)  DELETE FROM "users" WHERE "users"."id" = 3

Redirected to http://10.0.0.4:3000/users
Completed 302 Found in 180ms
你能解释一下,为什么我从不发送任何令牌以及那些请求时我能做什么?     
已邀请:
非常短版本:
protect_from_forgery
旨在防止来自伪造的HTML FORM元素的XSRF攻击。 PUT和DELETE不容易受到XSRF攻击,因为HTML表单不能使用PUT或DELETE。 XSRF(跨站点请求伪造)攻击是受害者浏览器被欺骗向服务器提交伪造请求而无需用户交互的地方。 更长版本:您能够做到这一点的原因是: 无需安全/登录,或 已经登录并正在从托管在同一域上的脚本发出请求,或者 通过Fiddler或类似方式提出请求(绕过浏览器的内置保护)。 这些不是场景
protect_from_forgery
旨在防范。
protect_from_forgery
的目的是防止XSRF攻击 - 跨站点请求伪造。当访问邪恶网站(或添加了恶意的好网站)的用户被欺骗向另一个网站提交请求时,就会发生这种情况。例如,您可以欺骗访问者发出任何GET请求,如下所示:
<img src="http://victim.com/victimPage?action=delete&id=ID12345" />
一旦受害者访问Evil站点,他的浏览器将自动尝试检索图像。这显然不会检索图像,但同时victim.com将执行删除项目ID12345的请求。 POST可以以类似的方式伪造,只需创建一个表单,然后使用脚本将其提交到外部站点,或者诱骗用户单击它以进行提交。 这就是
protect_from_forgery
的用武之地:服务器将令牌发送到带有表单的隐藏字段中的客户端。如果没有出现有效令牌,则服务器断定所提交的表单不是服务器发送的真实表单的提交,因此请求将被拒绝,因为可能是伪造的。 但你知道的。 关键是HTTP表单只能使用GET和POST方法,而不能使用PUT或DELETE。这有两个影响: 首先,如果你得到PUT或DELETE,就没有地方可以放置
protect_from_forgery
令牌。 PUT或DELETE不是表单提交的结果,因此服务器无法将令牌发送到客户端,因此客户端没有令牌可以发回。 其次,由于HTML表单只能使用POST和GET,如果请求是PUT或DELETE,则攻击者无法使用HTML表单强制或欺骗用户提交请求。他们可以使用XMLHttpRequest,但XMLHttpRequest不允许跨站点请求(除非两个站点上的安全设置启用)。 这意味着,如果您托管它的域不包含恶意代码本身,则不必保护PUT和DELETE免遭伪造。如果服务器确实包含恶意代码,则攻击者可以发出任意XMLHttpRequest请求以获取有效令牌,因此无论如何都可以轻松绕过伪造保护。 有关XSRF的快速说明,请尝试此处: http://blogs.msdn.com/b/bryansul/archive/2008/08/15/rest-and-xsrf-part-one.aspx     

要回复问题请先登录注册