Skip to content

Commit 68a79df

Browse files
Copilotfletchto99
andcommitted
Fix content_security_policy_nonce to work without parameters for Rails compatibility
Co-authored-by: fletchto99 <[email protected]>
1 parent 3b6aefe commit 68a79df

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

lib/secure_headers/view_helper.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,11 @@ def nonced_stylesheet_pack_tag(*args, &block)
6565
# Public: use the content security policy nonce for this request directly.
6666
# Instructs secure_headers to append a nonce to style/script-src directives.
6767
#
68+
# type - The type of nonce to generate (:script or :style). Defaults to :script
69+
# to match Rails' content_security_policy_nonce behavior.
70+
#
6871
# Returns a non-html-safe nonce value.
69-
def _content_security_policy_nonce(type)
72+
def _content_security_policy_nonce(type = :script)
7073
case type
7174
when :script
7275
SecureHeaders.content_security_policy_script_nonce(@_request)

spec/lib/secure_headers/view_helpers_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,5 +188,64 @@ module SecureHeaders
188188
expect(env[ContentSecurityPolicyConfig::HEADER_NAME]).not_to match(/rails-nonce/)
189189
end
190190
end
191+
192+
it "supports calling content_security_policy_nonce without parameters (Rails compatibility)" do
193+
begin
194+
allow(SecureRandom).to receive(:base64).and_return("xyz789")
195+
196+
# Create a test class that simulates what GoodJob does
197+
# They call content_security_policy_nonce without any parameters
198+
test_class = Class.new(Message) do
199+
def self.template
200+
<<-TEMPLATE
201+
<script nonce="<%= content_security_policy_nonce %>">
202+
console.log("test")
203+
</script>
204+
TEMPLATE
205+
end
206+
end
207+
208+
message = test_class.new(request)
209+
result = message.result
210+
211+
# The nonce should be included in the rendered output
212+
expect(result).to include('nonce="xyz789"')
213+
214+
# Call middleware to generate headers
215+
_, env = middleware.call request.env
216+
217+
# The nonce should be added to script-src in the CSP header (default behavior)
218+
expect(env[ContentSecurityPolicyConfig::HEADER_NAME]).to match(/script-src[^;]*'nonce-xyz789'/)
219+
end
220+
end
221+
222+
it "supports calling content_security_policy_nonce with :style parameter" do
223+
begin
224+
allow(SecureRandom).to receive(:base64).and_return("style123")
225+
226+
# Create a test class that calls content_security_policy_nonce with :style
227+
test_class = Class.new(Message) do
228+
def self.template
229+
<<-TEMPLATE
230+
<style nonce="<%= content_security_policy_nonce(:style) %>">
231+
body { background: red; }
232+
</style>
233+
TEMPLATE
234+
end
235+
end
236+
237+
message = test_class.new(request)
238+
result = message.result
239+
240+
# The nonce should be included in the rendered output
241+
expect(result).to include('nonce="style123"')
242+
243+
# Call middleware to generate headers
244+
_, env = middleware.call request.env
245+
246+
# The nonce should be added to style-src in the CSP header
247+
expect(env[ContentSecurityPolicyConfig::HEADER_NAME]).to match(/style-src[^;]*'nonce-style123'/)
248+
end
249+
end
191250
end
192251
end

0 commit comments

Comments
 (0)