-
Add
content_typeoption to HTTP authentication methods.request_http_basic_authentication,request_http_digest_authentication, andrequest_http_token_authenticationnow accept acontent_typeparameter to control the Content-Type of the 401 response. The default behavior is unchanged.http_basic_authenticate_with( name: "admin", password: "secret", message: '{"error":"Access denied"}', content_type: "application/json" )
Iliana Hadzhiatanasova
-
Add
RAILS_HOST_APP_PATHenvironment variable to support editor links in devcontainer/Docker environments.When Rails runs inside a container, file paths in error pages are container-internal paths that don't exist on the host machine. Setting
RAILS_HOST_APP_PATHto the host's application path enables proper translation of container paths to host paths for editor links.Example in
.devcontainer/devcontainer.json:{ "containerEnv": { "EDITOR": "code", "RAILS_HOST_APP_PATH": "${localWorkspaceFolder}" } }This allows the "open in editor" feature to work correctly when developing in containers.
Victor Cobos
-
Make
event_backtraceattribute inrescue_from_handled.action_controllernotifications the full backtrace, whenconfig.action_controller.rescue_from_event_backtraceis:array.This also affects
action_controller.rescue_from_handledevents.zzak
-
Avoid loading
ActionController::Liveearly in initializer, and introduceaction_controller_liveload hook.Adrianna Chang
-
Make CSRF header-only protection compatible with local installs using HTTP
In local installations that don't use HTTPS and where the app is accessed within a local network, requests won't be performed from a secure context. In this case, the browser won't send the
Sec-Fetch-Siteheader. This means non-GET requests will be rejected because CSRF protection will fail when using the header-only approach.With this change, we allow these requests with missing
Sec-Fetch-Siteheaders if:- They happen over HTTP
- The app is not configured to force SSL
The
Origincheck always happens in any case.Rosa Gutierrez
-
Deprecate calling
protect_from_forgerywithout specifying a strategy.When
protect_from_forgeryis called without the:withoption, it currently defaults to:null_session. This is inconsistent withconfig.action_controller.default_protect_from_forgery, which uses:exception.A new configuration option
config.action_controller.default_protect_from_forgery_withhas been added to allow applications to configure the default strategy. It currently defaults to:null_sessionfor backwards compatibility, but will change to:exceptionin a future version of Rails.Applications can opt into the new behavior now by setting:
config.action_controller.default_protect_from_forgery_with = :exception
To silence the deprecation warning without changing behavior, explicitly pass the strategy:
protect_from_forgery with: :null_session
Said Kaldybaev
-
Add
ActionDispatch::Request#bearer_tokento extract the bearer token from the Authorization header. Bearer tokens are commonly used for API and MCP requests.DHH
-
Add block support to
ActionController::Parameters#mergeActionController::Parameters#mergenow accepts a block to resolve conflicts, consistent withHash#mergeandParameters#merge!.params1 = ActionController::Parameters.new(a: 1, b: 2) params2 = ActionController::Parameters.new(b: 3, c: 4) params1.merge(params2) { |key, old_val, new_val| old_val + new_val } # => #<ActionController::Parameters {"a"=>1, "b"=>5, "c"=>4} permitted: false>
Said Kaldybaev
-
Yield key to
ActionController::Parameters#fetchblockkey = params.fetch(:missing) { |missing_key| missing_key } key # => :missing key = params.fetch("missing") { |missing_key| missing_key } key # => "missing"
Sean Doyle
-
Add
config.action_controller.live_streaming_excluded_keysto control execution state sharing in ActionController::Live.When using ActionController::Live, actions are executed in a separate thread that shares state from the parent thread. This new configuration allows applications to opt-out specific state keys that should not be shared.
This is useful when streaming inside a
connected_toblock, where you may want the streaming thread to use its own database connection context.# config/application.rb config.action_controller.live_streaming_excluded_keys = [:active_record_connected_to_stack]
By default, all keys are shared.
Eileen M. Uchitelle
-
Add controller action source location to routes inspector.
The routes inspector now shows where controller actions are defined. In
rails routes --expanded, a new "Action Location" field displays the file and line number of each action method.On the routing error page, when
RAILS_EDITORorEDITORis set, a clickable ✏️ icon appears next to each Controller#Action that opens the action directly in the editor.Guillermo Iguaran
-
Active Support notifications for CSRF warnings.
Switches from direct logging to event-driven logging, allowing others to subscribe to and act on CSRF events:
csrf_token_fallback.action_controllercsrf_request_blocked.action_controllercsrf_javascript_blocked.action_controller
Jeremy Daer
-
Modern header-based CSRF protection.
Modern browsers send the
Sec-Fetch-Siteheader to indicate the relationship between request initiator and target origins. Rails now uses this header to verify same-origin requests without requiring authenticity tokens.Two verification strategies are available via
protect_from_forgery using::-
:header_only- UsesSec-Fetch-Siteheader only. Rejects requests without a valid header. Default for new Rails 8.2 applications. -
:header_or_legacy_token- UsesSec-Fetch-Siteheader when present, falls back to authenticity token verification for older browsers.
Configure trusted origins for legitimate cross-site requests (OAuth callbacks, third-party embeds) with
trusted_origins::protect_from_forgery trusted_origins: %w[ https://accounts.google.com ]
InvalidAuthenticityTokenis deprecated in favor ofInvalidCrossOriginRequest.Rosa Gutierrez
-
-
Fix
action_dispatch_requestearly load hook call when building Rails app middleware.Gannon McGibbon
-
Emit a structured event when
action_on_open_redirectis set to:notifyin addition to the existing Active Support Notification.Adrianna Chang, Hartley McGuire
-
Support
text/markdownformat inDebugExceptionsmiddleware.When
text/markdownis requested via the Accept header, error responses are returned withContent-Type: text/markdowninstead of HTML. The existing text templates are reused for markdown output, allowing CLI tools and other clients to receive byte-efficient error information.Guillermo Iguaran
-
Support dynamic
to:andwithin:options inrate_limit.The
to:andwithin:options now accept callables (lambdas or procs) and method names (as symbols), in addition to static values. This allows for dynamic rate limiting based on user attributes or other runtime conditions.class APIController < ApplicationController rate_limit to: :max_requests, within: :time_window, by: -> { current_user.id } private def max_requests current_user.premium? ? 1000 : 100 end def time_window current_user.premium? ? 1.hour : 1.minute end end
Murilo Duarte
-
Define
ActionController::Parameters#deconstruct_keysto support pattern matchingif params in { search:, page: } Article.search(search).limit(page) else … end case (value = params[:string_or_hash_with_nested_key]) in String # do something with a String `value`… in { nested_key: } # do something with `nested_key` or `value` else # … end
Sean Doyle
-
Submit test requests using
as: :htmlwithContent-Type: x-www-form-urlencodedSean Doyle
-
Add
svg:renderer:class Page def to_svg body end end class PagesController < ActionController::Base def show @page = Page.find(params[:id]) respond_to do |format| format.html format.svg { render svg: @page } end end end
Thiago Youssef
Please check 8-1-stable for previous changes.