@@ -22,6 +22,9 @@ module ActionDispatch # :nodoc:
2222 # policy.report_uri "/csp-violation-report-endpoint"
2323 # end
2424 class ContentSecurityPolicy
25+ class InvalidDirectiveError < StandardError
26+ end
27+
2528 class Middleware
2629 CONTENT_TYPE = "Content-Type"
2730 POLICY = "Content-Security-Policy"
@@ -316,9 +319,9 @@ def build_directives(context, nonce, nonce_directives)
316319 @directives . map do |directive , sources |
317320 if sources . is_a? ( Array )
318321 if nonce && nonce_directive? ( directive , nonce_directives )
319- "#{ directive } #{ build_directive ( sources , context ) . join ( ' ' ) } 'nonce-#{ nonce } '"
322+ "#{ directive } #{ build_directive ( directive , sources , context ) . join ( ' ' ) } 'nonce-#{ nonce } '"
320323 else
321- "#{ directive } #{ build_directive ( sources , context ) . join ( ' ' ) } "
324+ "#{ directive } #{ build_directive ( directive , sources , context ) . join ( ' ' ) } "
322325 end
323326 elsif sources
324327 directive
@@ -328,8 +331,22 @@ def build_directives(context, nonce, nonce_directives)
328331 end
329332 end
330333
331- def build_directive ( sources , context )
332- sources . map { |source | resolve_source ( source , context ) }
334+ def validate ( directive , sources )
335+ sources . flatten . each do |source |
336+ if source . include? ( ";" ) || source != source . gsub ( /[[:space:]]/ , "" )
337+ raise InvalidDirectiveError , <<~MSG . squish
338+ Invalid Content Security Policy #{ directive } : "#{ source } ".
339+ Directive values must not contain whitespace or semicolons.
340+ Please use multiple arguments or other directive methods instead.
341+ MSG
342+ end
343+ end
344+ end
345+
346+ def build_directive ( directive , sources , context )
347+ resolved_sources = sources . map { |source | resolve_source ( source , context ) }
348+
349+ validate ( directive , resolved_sources )
333350 end
334351
335352 def resolve_source ( source , context )
0 commit comments