Class: Otto::Security::CSRFEnforcementWrapper
- Inherits:
-
Object
- Object
- Otto::Security::CSRFEnforcementWrapper
- Includes:
- CSRFValidation
- Defined in:
- lib/otto/security/csrf_enforcement_wrapper.rb
Overview
Per-route CSRF enforcement, applied at the handler layer.
CSRF enforcement lives here rather than in the global +CSRFMiddleware+ because +csrf=exempt+ is a per-route option: it is only known once a route has been matched (the middleware runs ahead of route matching and never sees route options, so a global block could not honor exemption — issue #186). This wrapper runs after matching, alongside +RouteAuthWrapper+, where +route_definition.csrf_exempt?+ is directly available. It is composed by +HandlerFactory+ only when CSRF protection is enabled, and wraps outside +RouteAuthWrapper+ so a forged unsafe request is rejected before any authentication work runs.
The global +CSRFMiddleware+ retains only token injection into HTML responses (a response-shaping concern that is method/content-type based, not route based, so it stays global).
Constant Summary
Constants included from CSRFValidation
Otto::Security::CSRFValidation::CSRF_ERROR_BODY, Otto::Security::CSRFValidation::SAFE_METHODS
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#route_definition ⇒ Object
readonly
Returns the value of attribute route_definition.
-
#wrapped_handler ⇒ Object
readonly
Returns the value of attribute wrapped_handler.
Instance Method Summary collapse
-
#call(env, extra_params = {}) ⇒ Array
Rack response tuple.
-
#initialize(wrapped_handler, route_definition, config) ⇒ CSRFEnforcementWrapper
constructor
A new instance of CSRFEnforcementWrapper.
Constructor Details
#initialize(wrapped_handler, route_definition, config) ⇒ CSRFEnforcementWrapper
Returns a new instance of CSRFEnforcementWrapper.
32 33 34 35 36 |
# File 'lib/otto/security/csrf_enforcement_wrapper.rb', line 32 def initialize(wrapped_handler, route_definition, config) @wrapped_handler = wrapped_handler @route_definition = route_definition @config = config end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
27 28 29 |
# File 'lib/otto/security/csrf_enforcement_wrapper.rb', line 27 def config @config end |
#route_definition ⇒ Object (readonly)
Returns the value of attribute route_definition.
27 28 29 |
# File 'lib/otto/security/csrf_enforcement_wrapper.rb', line 27 def route_definition @route_definition end |
#wrapped_handler ⇒ Object (readonly)
Returns the value of attribute wrapped_handler.
27 28 29 |
# File 'lib/otto/security/csrf_enforcement_wrapper.rb', line 27 def wrapped_handler @wrapped_handler end |
Instance Method Details
#call(env, extra_params = {}) ⇒ Array
Returns Rack response tuple.
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/otto/security/csrf_enforcement_wrapper.rb', line 41 def call(env, extra_params = {}) return wrapped_handler.call(env, extra_params) unless enforce?(env) request = Otto::Request.new(env) return wrapped_handler.call(env, extra_params) if valid_csrf_token?(request) Otto.structured_log(:warn, 'CSRF validation failed', Otto::LoggingHelpers.request_context(env).merge( handler: route_definition.definition, referrer: request.referrer )) csrf_error_response end |