Skip to content

Conversation

@AbanoubGhadban
Copy link
Collaborator

@AbanoubGhadban AbanoubGhadban commented Feb 12, 2026

Fixes #2350

The immediate hydration inline <script> tags in pro_helper.rb (generate_component_script and generate_store_script) were missing the CSP nonce attribute, causing browsers to block them when strict Content Security Policy is enabled.

Changes

  • Extract reusable csp_nonce method from wrap_console_script_with_nonce in helper.rb
  • Pass nonce: csp_nonce to both immediate hydration content_tag(:script, ...) calls in pro_helper.rb
  • Add unit tests for csp_nonce, generate_component_script, and generate_store_script

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added CSP nonce helper method for improved script security handling
    • Automatic nonce attribute injection for component and store hydration scripts
  • Improvements

    • Enhanced Content Security Policy compatibility across Rails versions
    • Consolidated nonce retrieval logic to reduce code duplication
  • Tests

    • Expanded test coverage for CSP nonce scenarios and Rails compatibility

AbanoubGhadban and others added 2 commits February 12, 2026 14:11
Extract reusable `csp_nonce` method from `wrap_console_script_with_nonce`
and use it in `generate_component_script` and `generate_store_script` so
that immediate hydration inline scripts include the CSP nonce attribute
when Content Security Policy is enabled.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- `#csp_nonce` tests: keep singleton methods (necessary since
  `content_security_policy_nonce` doesn't exist on the test helper and
  RSpec partial double verification blocks mocking nonexistent methods)
- `#generate_component_script`, `#generate_store_script`, and
  `#wrap_console_script_with_nonce` tests: mock `csp_nonce` directly
  instead of simulating the underlying Rails method

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@greptile-apps
Copy link

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR fixes a Content Security Policy (CSP) compliance issue where immediate hydration inline scripts were missing the nonce attribute, causing browsers to block them under strict CSP. The fix extracts the CSP nonce retrieval logic into a reusable csp_nonce method and applies it consistently to both component and store immediate hydration scripts.

Key Changes:

  • Extracted csp_nonce helper method with Rails version compatibility (5.2-6.0 fallback for ArgumentError)
  • Applied CSP nonce to immediate hydration scripts in generate_component_script and generate_store_script
  • Added comprehensive test coverage for all three methods with CSP enabled/disabled scenarios
  • Correctly omits nonce from application/json script tags (only executable scripts need CSP nonces)

The implementation follows the existing pattern from wrap_console_script_with_nonce and maintains backward compatibility with Rails 5.2-6.0.

Confidence Score: 5/5

  • This PR is safe to merge with no issues identified
  • The changes are well-structured with proper refactoring, comprehensive test coverage, and follow existing patterns. The implementation correctly handles CSP nonce for immediate hydration scripts while maintaining backward compatibility with older Rails versions.
  • No files require special attention

Important Files Changed

Filename Overview
react_on_rails/lib/react_on_rails/helper.rb Extracted csp_nonce method from wrap_console_script_with_nonce to make it reusable across helpers
react_on_rails/lib/react_on_rails/pro_helper.rb Added CSP nonce support to immediate hydration scripts in generate_component_script and generate_store_script
react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb Added comprehensive tests for csp_nonce, generate_component_script, and generate_store_script with CSP scenarios

Sequence Diagram

sequenceDiagram
    participant Browser
    participant RailsView
    participant Helper
    participant ProHelper
    
    Browser->>RailsView: Request page with React component
    RailsView->>ProHelper: generate_component_script(render_options)
    ProHelper->>Helper: csp_nonce()
    Helper->>Helper: Check respond_to?(:content_security_policy_nonce)
    alt CSP enabled
        Helper->>Helper: content_security_policy_nonce(:script)
        Helper-->>ProHelper: Return nonce value
    else CSP not enabled
        Helper-->>ProHelper: Return nil
    end
    
    alt immediate_hydration enabled
        ProHelper->>ProHelper: Create component spec JSON script
        ProHelper->>ProHelper: Create immediate hydration script with nonce
        ProHelper-->>RailsView: Component spec + immediate script
    else immediate_hydration disabled
        ProHelper->>ProHelper: Create component spec JSON script only
        ProHelper-->>RailsView: Component spec only
    end
    
    RailsView-->>Browser: HTML with script tags
    Browser->>Browser: Verify CSP nonce (if enabled)
    Browser->>Browser: Execute immediate hydration script
Loading

- Fix Layout/MultilineMethodCallBraceLayout in generate_store_script
- Replace double with instance_double for RSpec/VerifiedDoubles

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Walkthrough

This change introduces CSP nonce support to React on Rails by adding a public csp_nonce helper method for retrieving content security policy nonces, refactoring existing nonce handling logic, and applying nonces to immediate hydration inline scripts in the pro helper with comprehensive test coverage.

Changes

Cohort / File(s) Summary
CSP Nonce Helper
react_on_rails/lib/react_on_rails/helper.rb
Adds new public csp_nonce method to retrieve CSP script nonce with Rails version compatibility (handles ArgumentError fallback). Refactors wrap_console_script_with_nonce to use the extracted method, applying nonce to script tag options when available.
Immediate Hydration Nonce Support
react_on_rails/lib/react_on_rails/pro_helper.rb
Applies CSP nonce handling to immediate hydration inline scripts for both component and store hydration. Retrieves nonce via the new helper and passes it as script tag option when present.
Test Coverage
react_on_rails/spec/dummy/spec/helpers/react_on_rails_helper_spec.rb
Adds JavaScriptHelper to test class. Expands test suite to cover new csp_nonce method with Rails version compatibility scenarios, and validates nonce application in component/store script generation and console script wrapping with various hydration and CSP configurations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A nonce arrives upon the breeze,
Securing scripts with cryptic ease,
From helper's hand to hydration flow,
CSP rules now bless our show—
Rails versions bend, yet all will know! 🎭✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add CSP nonce to immediate hydration scripts' accurately summarizes the main change in the pull request, which is to add Content Security Policy nonce attributes to immediate hydration inline scripts.
Linked Issues check ✅ Passed The pull request successfully addresses all coding requirements from issue #2350: extracts a reusable csp_nonce method, applies it to generate_component_script and generate_store_script to add nonce attributes to immediate hydration inline scripts for CSP compatibility.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of adding CSP nonce support to immediate hydration scripts; test additions validate the nonce functionality and remain in scope.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2350-csp-nonce-hydration

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
react_on_rails/lib/react_on_rails/pro_helper.rb (1)

54-61: Consider extracting the repeated nonce-options pattern into a small helper.

Lines 27–28 and 54–55 duplicate the same two-line pattern:

nonce = csp_nonce
script_options = nonce.present? ? { nonce: nonce } : {}

A tiny private method (e.g., csp_nonce_options) returning the hash would DRY this up and keep both call sites in sync.

♻️ Proposed helper in helper.rb (next to csp_nonce)
+    # Returns script tag options hash with nonce if CSP is enabled, empty hash otherwise.
+    def csp_nonce_script_options
+      nonce = csp_nonce
+      nonce.present? ? { nonce: nonce } : {}
+    end

Then in pro_helper.rb:

-                   nonce = csp_nonce
-                   script_options = nonce.present? ? { nonce: nonce } : {}
-                   immediate_script = content_tag(:script, %(
+                   immediate_script = content_tag(:script, %(
   ...
-        ).html_safe, script_options)
+        ).html_safe, csp_nonce_script_options)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@justin808 justin808 merged commit 208655d into master Feb 13, 2026
25 checks passed
@justin808 justin808 deleted the 2350-csp-nonce-hydration branch February 13, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add nonce attribute to immediate hydration inline scripts for CSP compatibility

3 participants