Skip to content

feat: opt-in CSRF protection for dashboard actions#40

Open
TakuroOnoda wants to merge 2 commits into
vishaltps:mainfrom
TakuroOnoda:feature/csrf-compatibility
Open

feat: opt-in CSRF protection for dashboard actions#40
TakuroOnoda wants to merge 2 commits into
vishaltps:mainfrom
TakuroOnoda:feature/csrf-compatibility

Conversation

@TakuroOnoda

Copy link
Copy Markdown

Summary

Adds opt-in CSRF protection for the dashboard's destructive POST actions (retry / discard / pause / resume / execute / reject / remove / prune), gated behind a new csrf_protection_enabled config (default false).

Why opt-in (default off)

The gem renders raw HTML forms and doesn't assume a session store (it supports API-only apps).
Rails' CSRF tokens require a session, so enabling it by default would break session-less hosts.
Off by default = fully backward compatible.

Changes

  • New SolidQueueMonitor.csrf_protection_enabled (default false).
  • skip_before_action :verify_authenticity_token is now skipped only when protection is disabled. When enabled, unverified POSTs return 422; safe methods pass through.
  • Destructive forms embed a token via a new csrf_token_field helper; the layout adds csrf_meta_tags. Both render nothing when disabled.
  • Fixed the failed-jobs bulk submit to preserve the token (it previously stripped all hidden inputs).
  • README / CHANGELOG / initializer template updated.

Enable

SolidQueueMonitor.setup do |config|
  config.csrf_protection_enabled = true
end

Requires a session store, same-origin mount, and a non-api_only app.


Thanks for building and maintaining such a clean, lightweight gem.
I've tried to keep this change minimal and fully backward compatible.
Hope it's a useful addition, and I'd love to hear your thoughts. 🙂

Add `config.csrf_protection_enabled` (default false) so hosts with a
session store can enable Rails' CSRF protection for the dashboard's
destructive POST actions, on par with Sidekiq::Web.

When enabled, `verify_authenticity_token` is no longer skipped, all forms
embed an authenticity token via the `csrf_token_field` helper, and the
layout renders `csrf_meta_tags`. Disabled by default to keep working in
session-less / API-only hosts.
@TakuroOnoda TakuroOnoda marked this pull request as ready for review June 19, 2026 19:07
@TakuroOnoda TakuroOnoda requested a review from vishaltps as a code owner June 19, 2026 19:07
@TakuroOnoda

Copy link
Copy Markdown
Author

Hi @vishaltps 👋 Whenever you get a chance, I'd love a review on this PR.
Happy to tweak anything to fit the project's direction.
Thanks!

@vishaltps vishaltps left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Nice work on this, tested it locally against a session-backed app and the opt-in flow behaves exactly as described. 👍

One small, purely cosmetic note: the two helpers are both conditional on csrf_protection_enabled, but only one carries the _if_enabled suffix- csrf_meta_tags_if_enabled vs csrf_token_field. Would be nice to unify the naming so the pair reads consistently. Either direction works:

  • drop the suffix → csrf_meta_tags_if_enabled becomes csrf_meta_tags (but that would shadow Rails' built-in helper, so probably not this one), or
  • keep both explicit → e.g. csrf_token_fieldcsrf_token_field_if_enabled.

Given the shadowing concern, leaning toward making both explicit feels cleanest. Totally non-blocking - just a readability nit.

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.

2 participants