Skip to content

[dev] Add CSP report endpoint and generalise policy#5907

Merged
StephenHulme merged 9 commits into
developfrom
sh51/nonce-security-blob-2
Jul 9, 2026
Merged

[dev] Add CSP report endpoint and generalise policy#5907
StephenHulme merged 9 commits into
developfrom
sh51/nonce-security-blob-2

Conversation

@StephenHulme

@StephenHulme StephenHulme commented Jul 8, 2026

Copy link
Copy Markdown
Member

Closes #5713

Changes proposed in this pull request

  • Add nonce tags to Vite resources
  • Create a Content Security Policy controller to log CSP violation reports
  • Remove specific exceptions from CSP and use better general settings instead
  • Generates logs whenever a policy is violated:
    [WARN] [csp-report] {"csp-report":{"document-uri":"http://localhost:3000/admin/accessioning_tools","referrer":"http://localhost:3000/admin","violated-directive":"script-src-elem","effective-directive":"script-src-elem","original-policy":"default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; report-uri /csp-reports","disposition":"report","blocked-uri":"data","status-code":200,"script-sample":""}}
    
  • Logs can be parsed and analysed in Kibana

Warning

The policy policy.style_src_attr :unsafe_inline opens a hole in the CSP layer negating many of the benefits that a content security policy brings.
It is strongly recommended that any instances of inline style attributes be converted to Bootstrap classes or stylesheets.
Usages can be found using:

grep -rI --include=\*.html\* --exclude=\*.svg 'style=' app/ > style_src_attr.txt  

For more detail see https://centralcsp.com/docs/style-src-attr.

Informative resources

Official Rails Guide
Useful background
Specifications

Instructions for Reviewers

[All PRs] - Confirm PR template filled
[Feature Branches] - Review code
[Production Merges to main]
    - Check story numbers included
    - Check for debug code
    - Check version

@StephenHulme StephenHulme self-assigned this Jul 8, 2026
@StephenHulme StephenHulme requested review from BenTopping and Copilot and removed request for Copilot July 8, 2026 12:19
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.82%. Comparing base (375d7b5) to head (3cc3465).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #5907      +/-   ##
===========================================
- Coverage    84.85%   84.82%   -0.03%     
===========================================
  Files         1491     1492       +1     
  Lines        33931    33936       +5     
  Branches      3613     3613              
===========================================
- Hits         28791    28787       -4     
- Misses        4289     4302      +13     
+ Partials       851      847       -4     
Flag Coverage Δ
javascript 76.31% <ø> (ø)
ruby 84.71% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@BenTopping BenTopping left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to use config.content_security_policy_report_only = true report only to start with in case we have uncaught script executions

#
# The content security policy itself is defined in config/initializers/content_security_policy.rb
module ViteRailsNoncePatch
def vite_javascript_tag(*names, **options)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the alternative to this adding nonce: true to all vite_javascript_tag's?

@StephenHulme StephenHulme Jul 8, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, and that does work.

The UJS version is also defined in a central location:

config.content_security_policy_nonce_directives = %w(script-src style-src)

@StephenHulme

Copy link
Copy Markdown
Member Author

Would it make sense to use config.content_security_policy_report_only = true report only to start with in case we have uncaught script executions

Correct, this is already set.

This is mostly due to old jQuery, but could have other causes
This is due to legacy code and practises that need updating
@StephenHulme StephenHulme merged commit 3784a62 into develop Jul 9, 2026
17 of 18 checks passed
@StephenHulme StephenHulme deleted the sh51/nonce-security-blob-2 branch July 9, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants