-
-
Notifications
You must be signed in to change notification settings - Fork 632
Description
Summary
The immediate hydration scripts generated by generate_component_script and generate_store_script in lib/react_on_rails/pro_helper.rb (lines 27-29 and 52-55) create inline <script> tags without nonce attributes. This makes them incompatible with strict Content Security Policy (CSP) configurations.
Context
React on Rails already handles nonces correctly for console replay scripts via wrap_console_script_with_nonce in helper.rb (lines 440-464), which uses Rails' content_security_policy_nonce(:script) helper. The immediate hydration scripts should follow the same pattern.
Affected Code
lib/react_on_rails/pro_helper.rb:
# generate_component_script (line 27-29)
immediate_script = content_tag(:script, %(
typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsComponentLoaded('#{escaped_dom_id}');
).html_safe)
# generate_store_script (line 52-55)
immediate_script = content_tag(:script, <<~JS.strip_heredoc.html_safe
typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsStoreLoaded('#{escaped_store_name}');
JS
)Expected Behavior
When CSP is enabled with nonce-based script-src, these inline scripts should include the request nonce:
<script nonce="abc123...">
typeof ReactOnRails === 'object' && ReactOnRails.reactOnRailsComponentLoaded('...');
</script>Suggested Fix
Follow the same pattern as wrap_console_script_with_nonce — call content_security_policy_nonce(:script) and pass it as the nonce: option to content_tag(:script, ...).
Impact
Without this fix, apps that enable strict CSP (without 'unsafe-inline' in script-src) cannot use immediate hydration. The browser blocks the inline scripts, and components fail to hydrate immediately.
Apps with SSR disabled or immediate hydration disabled are not affected.