Skip to content

Commit

Permalink
Add rename_csp_helper_nonce_attribute actionview configuration
Browse files Browse the repository at this point in the history
Adds a configuration to rename the csp helper attribute name.

It's disabled by default currently until the JS libraries are updated to the
new attribute name and Rails can ship with a new default attribute name.

Fixes rails#51580
  • Loading branch information
codergeek121 committed May 3, 2024
1 parent d65fec4 commit fe3b34b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
14 changes: 14 additions & 0 deletions actionview/CHANGELOG.md
@@ -1,3 +1,17 @@
* Add a disabled configuration `rename_csp_helper_nonce_attribute` to rename the csp_meta_tag helper nonce attribute name
If enabled, it renames the `content` attribute to `nonce` to avoid certain kinds of value exfiltration attacks.

```
app.config.action_view.rename_csp_helper_nonce_attribute = true
<%= csp_meta_tag %>
# renders
<meta name="csp-nonce" nonce="..." />
# instead of
<meta name="csp-nonce" content="..." />
```

*Niklas Häusele*

* Add queries count to template rendering instrumentation

```
Expand Down
6 changes: 5 additions & 1 deletion actionview/lib/action_view/helpers/csp_helper.rb
Expand Up @@ -4,6 +4,9 @@ module ActionView
module Helpers # :nodoc:
# = Action View CSP \Helpers
module CspHelper
mattr_accessor :rename_csp_helper_nonce_attribute
self.rename_csp_helper_nonce_attribute = nil

# Returns a meta tag "csp-nonce" with the per-session nonce value
# for allowing inline <script> tags.
#
Expand All @@ -17,7 +20,8 @@ module CspHelper
def csp_meta_tag(**options)
if content_security_policy?
options[:name] = "csp-nonce"
options[:content] = content_security_policy_nonce
nonce_attribute_name = rename_csp_helper_nonce_attribute ? :nonce : :content
options[nonce_attribute_name] = content_security_policy_nonce
tag("meta", options)
end
end
Expand Down
6 changes: 6 additions & 0 deletions actionview/lib/action_view/railtie.rb
Expand Up @@ -14,9 +14,15 @@ class Railtie < Rails::Engine # :nodoc:
config.action_view.image_decoding = nil
config.action_view.apply_stylesheet_media_default = true
config.action_view.prepend_content_exfiltration_prevention = false
config.action_view.rename_csp_helper_nonce_attribute = false

config.eager_load_namespaces << ActionView

config.after_initialize do |app|
ActionView::Helpers::CspHelper.rename_csp_helper_nonce_attribute =
app.config.action_view.delete(:rename_csp_helper_nonce_attribute)
end

config.after_initialize do |app|
ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
app.config.action_view.delete(:embed_authenticity_token_in_remote_forms)
Expand Down
15 changes: 14 additions & 1 deletion actionview/test/template/csp_helper_test.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "abstract_unit"
require "active_support/core_ext/object/with"

class CspHelperWithCspEnabledTest < ActionView::TestCase
tests ActionView::Helpers::CspHelper
Expand All @@ -13,7 +14,19 @@ def content_security_policy?
true
end

def test_csp_meta_tag
def test_csp_meta_tag_uses_nonce_attribute_name_with_helper_nonce_attribute_enabled
ActionView::Helpers::CspHelper.with(rename_csp_helper_nonce_attribute: true) do
assert_equal "<meta name=\"csp-nonce\" nonce=\"iyhD0Yc0W+c=\" />", csp_meta_tag
end
end

def test_csp_meta_tag_uses_content_attribute_name_with_helper_nonce_attribute_disabled
ActionView::Helpers::CspHelper.with(rename_csp_helper_nonce_attribute: false) do
assert_equal "<meta name=\"csp-nonce\" content=\"iyhD0Yc0W+c=\" />", csp_meta_tag
end
end

def test_csp_meta_tag_with_helper_nonce_attribute_default_setting
assert_equal "<meta name=\"csp-nonce\" content=\"iyhD0Yc0W+c=\" />", csp_meta_tag
end

Expand Down

0 comments on commit fe3b34b

Please sign in to comment.