DEV: Support passing relative URLs CSP builder (#19176)
Raw paths like `/test/path` are not supported natively in the CSP. This commit prepends the site's base URL to these paths. This allows plugins to add 'local' assets to the CSP without needing to hardcode the site's hostname.
This commit is contained in:
parent
a34838d671
commit
174a8b431b
|
@ -27,12 +27,13 @@ class ContentSecurityPolicy
|
|||
|
||||
def initialize(base_url:)
|
||||
@directives = Default.new(base_url: base_url).directives
|
||||
@base_url = base_url
|
||||
end
|
||||
|
||||
def <<(extension)
|
||||
return unless valid_extension?(extension)
|
||||
|
||||
extension.each { |directive, sources| extend_directive(normalize(directive), sources) }
|
||||
extension.each { |directive, sources| extend_directive(normalize_directive(directive), sources) }
|
||||
end
|
||||
|
||||
def build
|
||||
|
@ -51,20 +52,27 @@ class ContentSecurityPolicy
|
|||
|
||||
private
|
||||
|
||||
def normalize(directive)
|
||||
def normalize_directive(directive)
|
||||
directive.to_s.gsub('-', '_').to_sym
|
||||
end
|
||||
|
||||
def normalize_source(source)
|
||||
if source.starts_with?("/")
|
||||
"#{@base_url}#{source}"
|
||||
else
|
||||
source
|
||||
end
|
||||
rescue URI::ParseError
|
||||
source
|
||||
end
|
||||
|
||||
def extend_directive(directive, sources)
|
||||
return unless extendable?(directive)
|
||||
|
||||
@directives[directive] ||= []
|
||||
|
||||
if sources.is_a?(Array)
|
||||
@directives[directive].concat(sources)
|
||||
else
|
||||
@directives[directive] << sources
|
||||
end
|
||||
sources = Array(sources).map { |s| normalize_source(s) }
|
||||
@directives[directive].concat(sources)
|
||||
|
||||
@directives[directive].delete(:none) if @directives[directive].count > 1
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# authors: xrav3nz
|
||||
|
||||
extend_content_security_policy(
|
||||
script_src: ['https://from-plugin.com'],
|
||||
script_src: ['https://from-plugin.com', '/local/path'],
|
||||
object_src: ['https://test-stripping.com'],
|
||||
frame_ancestors: ['https://frame-ancestors-plugin.ext'],
|
||||
manifest_src: ['https://manifest-src.com']
|
||||
|
|
|
@ -222,6 +222,7 @@ RSpec.describe ContentSecurityPolicy do
|
|||
|
||||
plugin.enabled = true
|
||||
expect(parse(policy)['script-src']).to include('https://from-plugin.com')
|
||||
expect(parse(policy)['script-src']).to include('http://test.localhost/local/path')
|
||||
expect(parse(policy)['object-src']).to include('https://test-stripping.com')
|
||||
expect(parse(policy)['object-src']).to_not include("'none'")
|
||||
expect(parse(policy)['manifest-src']).to include("'self'")
|
||||
|
|
Loading…
Reference in New Issue