如何在Rails 4中覆盖控制器或操作的X-Frame-Options

Chr*_*ers 84 iframe ruby-on-rails http-headers x-frame-options ruby-on-rails-4

导轨4次出现设置的默认值SAMEORIGINX-Frame-OptionsHTTP响应报头.这非常适合安全性,但它不允许您的应用程序的某些部分iframe在不同的域中可用.

您可以X-Frame-Options使用以下config.action_dispatch.default_headers设置覆盖全局值:

config.action_dispatch.default_headers['X-Frame-Options'] = "ALLOW-FROM https://apps.facebook.com"
Run Code Online (Sandbox Code Playgroud)

但是,如何仅针对单个控制器或操作覆盖它?

Chr*_*ers 131

如果要完全删除标题,可以创建after_action过滤器:

class FilesController < ApplicationController
  after_action :allow_iframe, only: :embed

  def embed
  end

private

  def allow_iframe
    response.headers.except! 'X-Frame-Options'
  end
end
Run Code Online (Sandbox Code Playgroud)

或者,当然,您可以编写代码after_action来将值设置为不同的值:

class FacebookController < ApplicationController
  after_action :allow_facebook_iframe

private

  def allow_facebook_iframe
    response.headers['X-Frame-Options'] = 'ALLOW-FROM https://apps.facebook.com'
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,您需要在调试时清除某些浏览器(Chrome for me)中的缓存.

  • 截至目前,无法在Chrome中使用。控制台错误是“加载'child'时遇到无效的'X-Frame-Options'标头:'ALLOW-FROM parent'不是公认的指令。标头将被忽略。” 在Chromium中被标记为“无法修复”,并带有另一种选择:“'frame-ancestors'在Chrome和Firefox中均已发布,并且是支持此功能的正确方法。” https://bugs.chromium.org/p/chromium/issues/detail?id=129139 (2认同)

arm*_*ent 14

我只是想在这里为任何在尝试弄清楚如何允许您的 Rails 应用程序嵌入 I-Frame 并遇到问题时找到此链接的人提供更新的答案。

在撰写本文时,即 2020 年 5 月 28 日,X-Frame-Options 更改可能不是您问题的最佳解决方案。“ALLOW-FROM”选项已被所有主要浏览器完全禁止。

现代解决方案是实施 Content-Security-Policy 并设置“frame_ancestors”策略。'frame_ancestors' 键指定哪些域可以将您的应用程序嵌入为 iframe。它目前受主要浏览器支持并覆盖您的 X-Frame-Options。这将允许您防止点击劫持(X-Frame-Options 最初旨在帮助它在很大程度上被弃用之前提供帮助)并在现代环境中锁定您的应用程序。

您可以在初始化程序中使用 Rails 5.2 设置内容安全策略(下面的示例),对于 Rails < 5.2,您可以使用像 Secure Headers gem 这样的 gem:https : //github.com/github/secure_headers

如果您愿意,您还可以在控制器/操作的基础上覆盖策略规范。

内容安全策略非常适合高级安全保护。查看您可以在 Rails 文档中配置的所有内容:https : //edgeguides.rubyonrails.org/security.html

内容安全策略的 Rails 5.2 示例:

# config/initializers/content_security_policy.rb    
    Rails.application.config.content_security_policy do |policy|
      policy.frame_ancestors :self, 'some_website_that_embeds_your_app.com'
    end
Run Code Online (Sandbox Code Playgroud)

控制器特定更改策略的示例:

# Override policy inline
class PostsController < ApplicationController
  content_security_policy do |p|
    p.frame_ancestors :self, 'some_other_website_that_can_embed_posts.com'
  end
end
Run Code Online (Sandbox Code Playgroud)