Class: Otto::Security::CSP::EmitMiddleware
- Inherits:
-
Object
- Object
- Otto::Security::CSP::EmitMiddleware
- Defined in:
- lib/otto/security/csp/emit_middleware.rb
Overview
Rack middleware that emits a nonce-based Content-Security-Policy on the way out — the EMITTING sibling of ReportMiddleware.
It is a passive BACKSTOP: it runs the CSP through Writer
in :backstop mode, so it fills the gap for responses that would
otherwise ship without a CSP but NEVER clobbers one a route or another
layer already set. All the emission invariants (enabled / HTML-only /
nonce-present / don’t-clobber / lowercase key) are the Writer’s, so this
middleware carries none of that guard logic itself.
DEFAULT: emit-if-consumed. It emits only when the request actually
consumed a nonce (a view called Request#csp_nonce, memoizing it
into the env). This is the safe default: a nonce-only script-src on an
HTML page whose templates never stamped that nonce would block EVERY
script on the page. “CSP responses whose request consumed a nonce” is
sound; “CSP all HTML responses” is not.
EAGER (opt-in): with eager: true it MINTS a nonce for every otherwise
eligible response, even one that never touched it. Only safe when the app
either uses no nonce-gated inline scripts or stamps the nonce another way;
otherwise it reintroduces the blocked-script hazard above.
INERT unless Otto::Security::Config#csp_nonce_enabled?. When nonce-CSP is off it is a transparent pass-through (and never mints a nonce).
Instance Method Summary collapse
-
#call(env) ⇒ Object
-
#initialize(app, config = nil, eager: false, development_mode: nil) ⇒ EmitMiddleware
constructor
A new instance of EmitMiddleware.
Constructor Details
#initialize(app, config = nil, eager: false, development_mode: nil) ⇒ EmitMiddleware
Returns a new instance of EmitMiddleware.
45 46 47 48 49 50 |
# File 'lib/otto/security/csp/emit_middleware.rb', line 45 def initialize(app, config = nil, eager: false, development_mode: nil) @app = app @config = config || Otto::Security::Config.new @eager = eager @development_mode = development_mode end |
Instance Method Details
#call(env) ⇒ Object
52 53 54 55 56 |
# File 'lib/otto/security/csp/emit_middleware.rb', line 52 def call(env) status, headers, body = @app.call(env) apply_backstop(env, headers) if @config.csp_nonce_enabled? [status, headers, body] end |