Skip to content

Commit ad2529b

Browse files
authored
Merge pull request rails#44578 from Edouard-chin/ec-directive-mapping
Apply content security policy mapping when generated dynamically:
2 parents 62b4ca9 + cdccbb4 commit ad2529b

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

actionpack/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
* Fix `content_security_policy` returning invalid directives.
2+
3+
Directives such as `self`, `unsafe-eval` and few others were not
4+
single quoted when the directive was the result of calling a lambda
5+
returning an array.
6+
7+
```ruby
8+
content_security_policy do |policy|
9+
policy.frame_ancestors lambda { [:self, "https://example.com"] }
10+
end
11+
```
12+
13+
With this fix the policy generated from above will now be valid.
14+
15+
*Edouard Chin*
16+
117
* Fix `skip_forgery_protection` to run without raising an error if forgery
218
protection has not been enabled / `verify_authenticity_token` is not a
319
defined callback.

actionpack/lib/action_dispatch/http/content_security_policy.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "active_support/core_ext/object/deep_dup"
4+
require "active_support/core_ext/array/wrap"
45

56
module ActionDispatch # :nodoc:
67
# Configures the HTTP
@@ -345,7 +346,7 @@ def resolve_source(source, context)
345346
raise RuntimeError, "Missing context for the dynamic content security policy source: #{source.inspect}"
346347
else
347348
resolved = context.instance_exec(&source)
348-
resolved.is_a?(Symbol) ? apply_mapping(resolved) : resolved
349+
apply_mappings(Array.wrap(resolved))
349350
end
350351
else
351352
raise RuntimeError, "Unexpected content security policy source: #{source.inspect}"

actionpack/test/dispatch/content_security_policy_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ def test_dynamic_directives
255255
assert_equal "script-src www.example.com", @policy.build(controller)
256256
end
257257

258+
def test_multiple_and_dynamic_directives
259+
request = ActionDispatch::Request.new("HTTP_HOST" => "www.example.com")
260+
controller = Struct.new(:request).new(request)
261+
262+
@policy.frame_ancestors -> { [:self, "https://example.com"] }
263+
assert_equal "frame-ancestors 'self' https://example.com", @policy.build(controller)
264+
end
265+
258266
def test_mixed_static_and_dynamic_directives
259267
@policy.script_src :self, -> { "foo.com" }, "bar.com"
260268
request = ActionDispatch::Request.new({})

0 commit comments

Comments
 (0)