Class: Sinatra::Inertia::CSRFMiddleware
- Inherits:
-
Object
- Object
- Sinatra::Inertia::CSRFMiddleware
- Defined in:
- lib/sinatra/inertia/csrf_middleware.rb
Overview
Rack middleware implementing the Inertia / Laravel "double-submit
cookie" CSRF pattern that @inertiajs/react and @inertiajs/vue3
honour out of the box.
Behaviour
- On every request, ensure a token cookie named
XSRF-TOKENis present (generate + set on the response if missing). - For non-safe methods (POST / PUT / PATCH / DELETE), require the
request to send
X-XSRF-TOKENwhose value matches the cookie. Mismatch →403 Forbidden. - The cookie is not HttpOnly — Inertia's client reads it from
document.cookieand forwards it asX-XSRF-TOKENautomatically.
Caveats
Double-submit cookie is the standard Inertia/Laravel pattern but is weaker than synchronizer-token CSRF when an attacker has any script-injection foothold. Pair with:
* `SameSite=Lax` (default below)
Configuration
set :inertia_csrf_protection, false disables this middleware. Use
this only when the consumer ships its own CSRF defence. Safer
defaults assume the gem is responsible.
Constant Summary collapse
- COOKIE_NAME =
"XSRF-TOKEN"- HEADER_KEY =
"HTTP_X_XSRF_TOKEN"- ENV_TOKEN_KEY =
"sinatra.inertia.csrf_token"- SAFE_METHODS =
%w[GET HEAD OPTIONS].freeze
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, same_site: :Lax) ⇒ CSRFMiddleware
constructor
A new instance of CSRFMiddleware.
Constructor Details
#initialize(app, same_site: :Lax) ⇒ CSRFMiddleware
44 45 46 47 |
# File 'lib/sinatra/inertia/csrf_middleware.rb', line 44 def initialize(app, same_site: :Lax) @app = app @same_site = same_site end |
Instance Method Details
#call(env) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/sinatra/inertia/csrf_middleware.rb', line 49 def call(env) existing = (env) token = existing || SecureRandom.urlsafe_base64(32) env[ENV_TOKEN_KEY] = token unless safe_method?(env) header = env[HEADER_KEY].to_s if existing.nil? || header.empty? || !secure_compare(header, existing) return (forbidden( "CSRF token mismatch (expected matching X-XSRF-TOKEN header to XSRF-TOKEN cookie)" )) end end status, headers, body = @app.call(env) (headers, token) unless existing == token [status, headers, body] end |