Add CSRF protection via Rack::Protection::AuthenticityToken#444
Open
mattimustang wants to merge 1 commit into
Open
Add CSRF protection via Rack::Protection::AuthenticityToken#444mattimustang wants to merge 1 commit into
mattimustang wants to merge 1 commit into
Conversation
Sinatra::Base subclasses do not enable Rack::Protection by default. This commit adds explicit CSRF protection for all state-changing endpoints. - Add Rack::Session::Cookie (SameSite=Strict, HttpOnly) to establish the session needed for CSRF token storage - Add Rack::Protection::AuthenticityToken to validate tokens on all non-safe requests (POST, PUT, DELETE, PATCH); skipped in the test environment so existing rack/test suites are unaffected - Add authenticity_token hidden input to the conf_search form in layout.haml (present on every page) and to the version-diff form in diffs.haml - Add three regression tests: CSRF token present in conf_search form, CSRF token present in diffs form, session cookie carries SameSite=Strict Fixes CWE-352 / CVSSv4.0 6.3 (CSRF on state-changing endpoints).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rack::Session::Cookie(SameSite=Strict, HttpOnly) to establish the session required for CSRF token storageRack::Protection::AuthenticityTokento validate tokens on all non-safe requests (POST, PUT, DELETE, PATCH); skipped in the test environment so existing rack/test suites are unaffected without needing to be rewrittenauthenticity_tokenhidden input to the conf_search form inlayout.haml(present on every page) and to the version-diff comparison form indiffs.hamlspec/web/csrf_spec.rb: CSRF token present in conf_search form, CSRF token present in diffs form, session cookie carries SameSite=StrictFixes CWE-352 / CVSSv4.0 6.3 — CSRF on all state-changing endpoints.
Why
Rack::Session::Cookieis always on (including test)Rack::Protection::AuthenticityTokenstores and retrieves the CSRF token via the Rack session (session[:csrf]). Without a session middleware the template callRack::Protection::AuthenticityToken.token(session)would crash on a nil session. The session middleware must be present whenever a page is rendered, including in tests.Why
Rack::Protection::AuthenticityTokenis skipped in testThe validation middleware is the piece that returns 403 for requests without a valid token. Every existing POST/PUT test (
put '/node/next/...', etc.) was written before CSRF protection existed and sends no token. Enabling validation in test would break the entire suite. The correctness of the validation logic is rack-protection's own responsibility (covered by its own tests); what we verify here is our side of the contract — that forms embed the token and the cookie carries the right attributes.Notes on GET state-changing endpoints
/reloadandGET /node/next/:nodeare state-changing GET routes that cannot be protected by form tokens. The SameSite=Strict session cookie provides defence-in-depth for same-site-restricted environments, but full protection would require converting these to POST endpoints (a separate, larger change).Test plan
rake test— 42 runs, 0 failures/nodes— confirm the conf_search form submits successfully (token round-trips correctly)rack.sessioncookie withSameSite=StrictandHttpOnly