Googlebot 在 Rails 4.1 上导致无效的跨域请求 (COR)

Posted

技术标签:

【中文标题】Googlebot 在 Rails 4.1 上导致无效的跨域请求 (COR)【英文标题】:Googlebot causes an invalid Cross Origin Request (COR) on Rails 4.1 【发布时间】:2014-09-02 15:30:21 【问题描述】:

如何防止 Google 在抓取网站时导致此错误?我对关闭“protect_from_forgery”不感兴趣,除非这样做是安全的。

[fyi] method=GET path=/users format=*/* controller=users action=show status=200 duration=690.32 view=428.25 db=253.06 time=  host= user= user_agent=Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) session= params="" ()
[hmm] Security warning: an embedded <script> tag on another site requested protected javascript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding. (pid:)
[fyi] method=GET path=/users/123/flag format=*/* controller=users action=flag status=500 error='ActionController::InvalidCrossOriginRequest:Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.' duration=26.50 time= host= user= user_agent= session= params= (pid)
[omg] ActionController::InvalidCrossOriginRequest (Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.):
actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:217:in `verify_same_origin_request'

控制器对此作出响应

respond_to do |format|
    format.js  render template: 'users/flag', layout: "some_layout" 
end

我无法重新创建错误,当我通过浏览器执行此错误时,它似乎工作正常

到目前为止,我已经查看了以下资源,但大多数似乎都建议只是盲目地转向 CSRF 或没有得到答复。

Using layout specific javascript in comfy leads to InvalidCrossOriginRequest Invalid Cross Origin Request After Upgrading to Rails 4.1 How to avoid ActionController::InvalidCrossOriginRequest exception? Googlebot asks for png and then my whole Heroku site crashes. What is going on? https://github.com/rails/rails/pull/13345 http://myownpirateradio.com/tag/rails-authentication-token/ https://gist.github.com/aishek/8535082 Why does Google prepend while(1); to their JSON responses? http://www.tsheffler.com/blog/?p=428 http://edgeapi.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html

澄清: 该操作应受 CSRF 保护,但我想防止 Google 抓取它或在抓取页面时生成错误。即)我希望在不影响我的安全功能的情况下消除误报安全警告。

【问题讨论】:

【参考方案1】:

Googlebot 使用格式“*/*”(http://apidock.com/rails/Mime) 并且应用程序呈现 js,因为它是唯一可用的东西。由于它是远程的,因此它正确地导致了 Invalid COR。

这可以通过以下方式重现:

curl -H "Accept: */*" https://www.example.com/users/123/flag

解决方法是为蜘蛛抓取一个 html 后备资源:

respond_to do |format|
  format.html  render template: 'users/flag' 
  format.js  render template: 'users/flag', layout: "some_layout" 
end

【讨论】:

排序在这里很重要。 format.html 应该在 response_to 块中的 format.js 之前。 我遇到了同样的问题,解决方案中描述的重现步骤对我不起作用,直到我将标题更改为 -H "Accept: */*",此时我现在可以重现错误。 此建议还会引发错误“安全警告:另一个站点上的嵌入式 【参考方案2】:

根据 Rails 指南中的“CSRF 保护远程标签”:

在测试的情况下,你也做客户端,从:

获取:索引,格式::js

收件人:

xhr :get, :index, 格式: :js

http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#csrf-protection-from-remote-script-tags

如果您想让该路由跳过 csrf 检查,请使用以下内容将该路由列入白名单:

protect_from_forgery :except => :create

【讨论】:

当您无法控制调用端点时,这是否可以解决问题?我已经更新了测试以使用它。 为了对调用者也进行管理(不仅是为了测试你控制客户端的地方),指南说:“如果你真的想从远程 问题中列出的答案绝对没有一个能解决这个问题!就我而言,application.js 是由机器人调用的。我应该只为这个文件关闭伪造保护吗?!

以上是关于Googlebot 在 Rails 4.1 上导致无效的跨域请求 (COR)的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 4.1 中将页面特定的 jQuery 代码放在哪里?

Rails 4.1 Mailer预览和设计自定义电子邮件

如何解决错误“‘生产’环境缺少‘secret_key_base’”(Rails 4.1)

Googlebot何时执行javascript?

忘记密码rails 4.1

在 Rails 4.1 中从选择中保存枚举