Module: Roda::RodaPlugins::SecFetchSiteCsrf
- Defined in:
- lib/roda/plugins/sec_fetch_site_csrf.rb
Overview
The sec_fetch_site plugin allows for CSRF protection using the Sec-Fetch-Site header added in modern browsers. It allows for CSRF protection without the use of CSRF tokens, which can simplify form creation.
The protection offered by the sec_fetch_site plugin is weaker than the protection offered by the route_csrf plugin with default settings, since it doesn’t support per-request tokens. Be aware you are trading security for simplicity when using the sec_fetch_site plugin instead of the route_csrf plugin. Other caveats in using the sec_fetch_site plugin:
-
Not all browsers set the Sec-Fetch-Site header. Some browsers didn’t start setting the header until 2023. In these cases, you need to decide how to handle the request. The default is to deny the request, though you can use the :allow_missing option to allow it.
-
Sec-Fetch-Site headers are not set for http requests, only https requests, so this doesn’t offer protection for http requests.
-
It isn’t possible to share a CSRF secret between applications in different origins to allow cross-site requests between the applications.
This plugin adds the check_sec_fetch_site! method to the routing block scope. You should call this method at the appropriate place in the routing tree to enforce the CSRF protection. The method can accept a block to override the :csrf_failure plugin option behavior on a per-call basis.
When loading the plugin with no options:
plugin :sec_fetch_site_csrf
Only same-origin requests are allowed by default.
This plugin supports the following options:
- :allow_missing
-
Whether to allow requests lacking the Sec-Fetch-Site header (false by default).
- :allow_none
-
Whether to allow requests where Sec-Fetch-Value is none (false by default).
- :allow_same_site
-
Whether to allow requests where Sec-Fetch-Value is same-site (false by default)
- :check_request_methods
-
Which request methods require CSRF protection (default:
['POST', 'DELETE', 'PATCH', 'PUT']) - :csrf_failure
-
The action to taken if a request does not have a valid header (default: :raise). Options:
- :raise
-
raise a Roda::RodaPlugins::SecFetchSiteCsrf::CsrfFailure exception
- :empty_403
-
return a blank 403 page
- :clear_session
-
clear the current session
The plugin also supports a block, in which case failures will call the block as a routing block (the block should accept the request object).
Defined Under Namespace
Modules: InstanceMethods Classes: CsrfFailure
Constant Summary collapse
- DEFAULTS =
{ :csrf_failure => :raise, :check_request_methods => %w'POST DELETE PATCH PUT'.freeze.each(&:freeze) }.freeze
Class Method Summary collapse
Class Method Details
.configure(app, opts = OPTS, &block) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/roda/plugins/sec_fetch_site_csrf.rb', line 71 def self.configure(app, opts=OPTS, &block) = app.opts[:sec_fetch_site_csrf] = (app.opts[:sec_fetch_site_csrf] || DEFAULTS).merge(opts) allowed_values = [:allowed_values] = ["same-origin"] allowed_values << "same-site" if opts[:allow_same_site] allowed_values << "none" if opts[:allow_none] allowed_values << nil if opts[:allow_missing] allowed_values.freeze if block [:csrf_failure] = :method app.define_roda_method(:_roda_sec_fetch_site_csrf_failure, 1, &app.send(:convert_route_block, block)) end case [:csrf_failure] when :raise, :empty_403, :clear_session, :method # nothing else raise RodaError, "Unsupported :csrf_failure plugin option: #{[:csrf_failure].inspect}" end .freeze end |