The content_security_policy
config can become unwieldy when supporting multiple 3rd party services. For example, the Intercom CSP v2 config is quite extensive.
I’m currently monkey-patching ActionDispatch::ContentSecurityPolicy
to add an append
method allowing me to merge CSP directives.
Rails.application.config.content_security_policy do |policy|
policy.script_src :self
# ...
# Youtube
policy.append do |youtube_policy|
youtube_policy.script_src "www.youtube.com"
# ...
end
# Google Analytics
policy.append do |ga_policy|
ga_policy.script_src "www.google-analytics.com"
# ...
end
# Intercom
# https://www.intercom.com/help/en/articles/3894-using-intercom-with-content-security-policy
policy.append do |intercom_policy|
intercom_policy.script_src "*.intercom.io", "*.intercomcdn.com"
# ...
end
end
It also makes it easier to make conditional directives.
if Rails.env.production?
# CDN
policy.append do |cdn_policy|
cdn_policy.script_src ENV["RAILS_ASSET_HOST"]
end
end
Here’s the monkey patch.
class ActionDispatch::ContentSecurityPolicy
def append(&block)
sub_policy = ActionDispatch::ContentSecurityPolicy.new(&block)
sub_policy.directives.each do |key, sources|
if @directives[key]
@directives[key] = @directives[key].concat(sources).uniq
else
@directives[key] = sources
end
end
end
end
Is this something that would fit in Rails core? If so I can turn it into a PR.