DEV: Automatically extend CSP when themes link to external scripts (#9531)
This commit is contained in:
parent
90d6816d19
commit
8a112b7464
|
@ -317,6 +317,7 @@ class ThemeField < ActiveRecord::Base
|
|||
self.value_baked, self.error = translation_field? ? process_translation : process_html(self.value)
|
||||
self.error = nil unless self.error.present?
|
||||
self.compiler_version = COMPILER_VERSION
|
||||
CSP::Extension.clear_theme_extensions_cache!
|
||||
elsif extra_js_field?
|
||||
self.value_baked, self.error = process_extra_js(self.value)
|
||||
self.error = nil unless self.error.present?
|
||||
|
|
|
@ -42,7 +42,9 @@ class ContentSecurityPolicy
|
|||
def find_theme_extensions(theme_ids)
|
||||
extensions = []
|
||||
|
||||
Theme.where(id: Theme.transform_ids(theme_ids)).find_each do |theme|
|
||||
resolved_ids = Theme.transform_ids(theme_ids)
|
||||
|
||||
Theme.where(id: resolved_ids).find_each do |theme|
|
||||
theme.cached_settings.each do |setting, value|
|
||||
extensions << build_theme_extension(value.split("|")) if setting.to_s == THEME_SETTING
|
||||
end
|
||||
|
@ -50,6 +52,21 @@ class ContentSecurityPolicy
|
|||
|
||||
extensions << build_theme_extension(ThemeModifierHelper.new(theme_ids: theme_ids).csp_extensions)
|
||||
|
||||
html_fields = ThemeField.where(
|
||||
theme_id: resolved_ids,
|
||||
target_id: ThemeField.basic_targets.map { |target| Theme.targets[target.to_sym] },
|
||||
name: ThemeField.html_fields
|
||||
)
|
||||
|
||||
auto_script_src_extension = { script_src: [] }
|
||||
html_fields.each(&:ensure_baked!)
|
||||
doc = html_fields.map(&:value_baked).join("\n")
|
||||
Nokogiri::HTML.fragment(doc).css('script[src]').each do |node|
|
||||
auto_script_src_extension[:script_src] << node['src']
|
||||
end
|
||||
|
||||
extensions << auto_script_src_extension
|
||||
|
||||
extensions
|
||||
end
|
||||
|
||||
|
|
|
@ -212,6 +212,19 @@ describe ContentSecurityPolicy do
|
|||
expect(parse(theme_policy)['script-src']).to_not include('https://from-theme-flag.script')
|
||||
expect(parse(theme_policy)['worker-src']).to_not include('from-theme-flag.worker')
|
||||
end
|
||||
|
||||
it 'is extended automatically when themes reference external scripts' do
|
||||
policy # call this first to make sure further actions clear the cache
|
||||
|
||||
theme.set_field(target: :common, name: "header", value: "<script src='https://example.com/myscript.js'/>")
|
||||
theme.save!
|
||||
|
||||
expect(parse(theme_policy)['script-src']).to include('https://example.com/myscript.js')
|
||||
|
||||
theme.destroy!
|
||||
|
||||
expect(parse(theme_policy)['script-src']).to_not include('https://example.com/myscript.js')
|
||||
end
|
||||
end
|
||||
|
||||
it 'can be extended by site setting' do
|
||||
|
|
Loading…
Reference in New Issue