如何以编程方式设置 content_security_policy?

How do I programmatically set a content_security_policy?

我正在为我们的 Rails 5.2 应用程序配置内容安全策略。我需要在我们的 CSP 中将一些域列入白名单。我想将域列表放在其他地方,以便我可以在应用程序的其他地方引用它们,然后从该列表以编程方式生成 CSP headers。

查看 source code for the Content Security Policy configuration mechanisms in Rails 5,似乎正在进行一些神奇的元编程,所以我不清楚如何完成我需要做的事情。看起来我需要调用来设置 headers 的函数可能 对它们的调用方式很挑剔。特别是,我不清楚我是否可以向它们传递数组或安全地多次调用它们,或者它们是否执行一些元编程魔法,只有当域作为单独的函数参数传入时才有效。

我可以像这样将一个数组传递给我想设置的 header 吗?

whitelisted_domains = ['https://example.com', 'self']

Rails.application.configure do
  config.content_security_policy do |csp|
    csp.child_src whitelisted_domains
  end
end

或者我可以像这样多次调用同一个函数吗?

whitelisted_domains = ['https://example.com', 'self']

Rails.application.configure do
  config.content_security_policy do |csp|
    whitelisted_domains.each {|domain| csp.child_src domain}
  end
end

如果这些都不起作用,那么完成我想做的事情的最佳方法是什么?

从源代码和文档中我可以看出,它需要一个数组。来自 rails 的 edgeguides,关注

Rails.application.config.content_security_policy do |policy|
  policy.default_src :self, :https
  ...
end

sourcecode,使用 *sources 作为参数;它相信它需要任何数量的参数,这意味着你可以按照以下方式做一些事情;

whitelisted_domains = ['https://example.com', 'self']

Rails.application.configure do
  config.content_security_policy do |csp|
    csp.child_src(*whitelisted_domains)
  end
end

https://blog.sqreen.io/integrating-content-security-policy-into-your-rails-applications-4f883eed8f45/

https://edgeguides.rubyonrails.org/security.html#content-security-policy

每个指令 define_method 的源代码 https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/content_security_policy.rb#L151

(注意:None 已经在 Rails 应用程序、简单的指南和 Rails 的源代码中进行了测试)