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


88

Rails 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"

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

Answers:


136

如果要完全删除标题,可以创建一个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

或者,当然,您可以对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

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


您如何将其用于redirect_to?(现在正在尝试使用我的Angular应用程序,但无法正常工作)
kittyminky 2014年

我假设包含redirect_to和的操作及其重定向到的操作都需要应用此操作。您是否遇到特定错误?听起来像是关于堆栈溢出的新问题!
克里斯·彼得斯

我意识到在将其重定向到重定向到路由的最终控制器操作after_action 之前,我已经有了Angular。谢谢!
kittyminky 2014年

它不要求这样做在after_action,尽管它是得心应手这样做例如,在Frontend::BaseController它适用于整个前端。您最好response.headers.except! ...在一个动作中运行。
编码人员

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

4

我只想在这里提供一个更新的答案,供试图找出如何允许将Rails应用程序嵌入I-Frame并遇到问题的人士找到此链接。

撰写本文时,2020年5月28日,X-Frame-Options更改可能不是您解决问题的最佳方法。所有主要的浏览器都完全不允许使用“ ALLOW-FROM”选项。

现代的解决方案是实施内容安全策略并设置“ frame_ancestors”策略。“ frame_ancestors”键指定哪些域可以将您的应用嵌入为iframe。目前主要浏览器都支持它,并且会覆盖您的X-Frame-Options。这将使您能够防止Clickjacking(X-Frame-Options最初旨在在不推荐使用此功能之前就提供帮助)并在现代环境中锁定您的应用程序。

您可以在初始化器中使用Rails 5.2设置Content-Security-Policy(以下示例),对于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

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

# 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

也可以使用lambda作为动态值:p.frame_ancestors :self, -> { company&.allowed_domain || 'none' }
Sharagoz

0

对于Rails 5+,请response.set_header('X-Frame-Options', 'ALLOW-FROM https://apps.facebook.com')改用。或者,如果ALLOW-FROM不起作用,并且需要快速修复,则可以将其设置为ALLOWALL

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.