Repository navigation
chore(deps): update dependency actionpack to v8.1.4.1 [security] - #1378
Open
renovate-bot wants to merge 1 commit into
Open
renovate-bot wants to merge 1 commit into
renovate-bot wants to merge 1 commit into
Conversation
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.
This PR contains the following updates:
8.1.4→8.1.4.1Action Pack: Possible restoration of destroyed sessions in Action Dispatch CacheStore
CVE-2026-126076 / GHSA-2586-8ghr-69fj
More information
Details
Impact
ActionDispatch::Session::CacheStorewrites a session back to the cache at the end of each request that loaded it, without checking that the session's cache entry still exists. When a concurrent request destroys the session, throughreset_sessionon logout or by deleting its cache entry on the server, a request that loaded the session earlier and finishes later restores it under its original session ID. Logout and server-side revocation could therefore fail to end a session, and an attacker who holds a stolen session cookie could keep that session valid across the victim's logout.Applications that use
config.session_store :cache_storeare affected, with any cache backend.ActionDispatch::Session::CookieStoreis not affected, nor isActionDispatch::Session::MemCacheStorewith Dalli 4.0.0 or later, whose session store does not write back a session that was deleted.Details
The fixed releases record which session a request loaded and skip the write when that session's cache entry no longer exists. Changes that such a request makes to the destroyed session are discarded, and Rack logs a warning that the session could not be saved. Each request that writes back a session it loaded makes one additional cache read.
Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
Credit
Found by the team during internal code review.
Severity
CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Action Pack: Possible IP spoofing in Action Dispatch RemoteIp
CVE-2026-126083 / GHSA-2gff-2mmg-m73p
More information
Details
Impact
Since Rails 8.1.0,
ActionDispatch::RemoteIpderivesrequest.remote_ipfromRack::Request#forwarded_for, which under Rack 3 reads the RFC 7239Forwardedheader in preference toX-Forwarded-For. When a reverse proxy appends the client address toX-Forwarded-Forbut passes a client-suppliedForwardedheader through unchanged,request.remote_ipreturns an address chosen by the client, and the IP spoofing check does not raise, because it compares onlyClient-Ipwith the forwarded addresses. An unauthenticated attacker could therefore spoofrequest.remote_ip, possibly bypassing IP-based access controls and rate limits keyed on the client address (including the defaultby:ofrate_limit), and falsifying the client address in logs.Details
The 8.1.0 change (2d084af8) switched
ActionDispatch::RemoteIpfrom readingX-Forwarded-Fordirectly to Rack'sforwarded_for, in order to reuse Rack's port handling. Rails continues to honorForwarded, the standard header.In the fixed releases, when
config.action_dispatch.ip_spoofing_checkis enabled (the default),ActionDispatch::RemoteIpalso compares the first untrusted client address inForwardedwith the first untrusted client address inX-Forwarded-For, as exact strings, and raisesActionDispatch::RemoteIp::IpSpoofAttackErrorwhen both headers are present and the addresses differ. Deployments whose proxies report the client address inconsistently between the two headers will receive this error after upgrading. See theactionpackCHANGELOG.Affected applications
An application is affected if it meets all of these requirements:
forwarded_forreads onlyX-Forwarded-For.Forwardedheader.request.remote_ipfor access control, rate limiting, or auditing.The fix detects a spoofed
Forwardedheader only when the proxy also setsX-Forwarded-For. An application whose proxy passes a client-suppliedForwardedheader through and sets noX-Forwarded-Forremains exposed after upgrading, and should configure the proxy to remove or overwriteForwarded, or apply the workaround below.Mitigation
actionpack.Forwardedheader.Workarounds
Applications whose proxies set
X-Forwarded-Forcan make Rack ignore theForwardedheader, restoring the client address resolution of Rails 8.0, by settingRack::Request.forwarded_priority = [:x_forwarded]in an initializer. This setting is available in Rack 3.0.0 and later, and it also causes Rack to ignoreForwardedwhen determining the request scheme, host, and port.Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
Versions affected
Credit
This issue was responsibly reported by HackerOne researcher luryus.
Severity
CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Action Pack: Possible cache poisoning in Action Pack content negotiation
CVE-2026-126073 / GHSA-r9jg-fmfx-2gv6
More information
Details
Impact
Action Pack negotiates the format of a rendered response from the
Accept,X-Requested-Withand, for XHR requests withoutAccept,Content-Typerequest headers, butActionController::Rendering#_set_vary_headeraddsVary: Acceptonly when the request carries a usableAcceptheader and the response has noVaryheader yet. A response to a request withoutAccept, or to an XHR request, therefore omits the headers that selected its representation, and a response whoseVarythe application set before rendering (for exampleVary: Accept-Language) never gainsAccept. A shared cache that honoursVarycould store such a response and serve it to later clients that request a different representation, possibly leading to cache poisoning in which visitors receive, until the entry expires, a page without its layout or HTML in place of JSON. The attacker cannot choose the content of the response.Applications that render negotiated responses from actions marked
public(for example withexpires_in ..., public: true) behind a shared cache that honoursVary, such as Thruster orRack::Cache, are affected.Details
In the fixed releases, a rendered response whose format is not given by the URL lists
AcceptandX-Requested-WithinVary, and alsoContent-Typefor an XHR request withoutAccept; whenconfig.action_dispatch.ignore_accept_headeris enabled, it lists onlyX-Requested-With. These fields are appended to an existingVaryvalue rather than skipped, andVary: *is left unchanged. Shared caches can store more variants of such responses than before. See the Action Pack CHANGELOG for details.Workarounds
Set
Vary: Accept, X-Requested-Withon negotiated responses in the application, for example in anafter_action, or do not mark negotiated responsespublic.Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
Credit
This issue was found by the Anthropic OSS Scanner (ANT-2026-7GHGLQGO, ANT-2026-5MT6C2R3).
Severity
CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:LReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Action Pack: Missing SameSite attribute on session cookies from Action Pack session stores
CVE-2026-126067 / GHSA-gmj8-hvj3-49mw
More information
Details
Impact
Action Pack session stores other than
ActionDispatch::Session::CookieStore(CacheStore,MemCacheStore, and third-party stores built onAbstractStore,AbstractSecureStoreor the session mixins) write the session cookie without aSameSiteattribute, regardless ofconfig.action_dispatch.cookies_same_site_protection, which defaults to:lax. OnlyCookieStoreapplies the configured policy. In browsers that do not treat a cookie without the attribute asSameSite=Lax, a cross-site request could carry the session cookie, possibly leading to cross-site request forgery against actions that do not verify an authenticity token, such as those of API-only applications.Applications are affected when they use a session store other than
CookieStoreand do not passsame_site:toconfig.session_store.Details
In the fixed releases, every session store sets the session cookie's
SameSiteattribute fromcookies_same_site_protectionwhen its options have no:same_sitekey. An explicitsame_site:option, includingsame_site: nil, and a:same_sitevalue in a store'sDEFAULT_OPTIONSstill take precedence.Workarounds
Pass
same_site:when configuring the session store, for exampleconfig.session_store :cache_store, same_site: :lax.Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
Credit
This issue was responsibly reported by HackerOne researcher tjvc.
Severity
CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
rails/rails (actionpack)
v8.1.4.1: 8.1.4.1Compare Source
Active Support
ActiveSupport::MessagePackno longer deserializes an unsafeActiveSupport::SafeBufferashtml_safe.A
SafeBufferthat was no longerhtml_safe?, for example after anin-place
gsub!, was deserialized as anhtml_safeSafeBuffer. It is nowserialized with an unsafe marker and deserialized as a
String. Earlierversions of Rails cannot read an unsafe buffer serialized this way.
[GHSA-2w9f-fxwj-w2qf]
Jean Boussier
ActiveSupport::Inflector#safe_constantizematches the constant name in aLoadErrormessage as a literal string instead of building aRegexpfrom it.
The name's segments were interpolated unescaped into the pattern, so input
that reaches
safe_constantize, such as the channel identifier in an ActionCable subscribe command, chose the source passed to the regexp compiler.
[GHSA-8474-xrp6-wh69]
Jeremy Daer
Active Model
Active Record
Action View
Skip attribute names in tag helpers that are blank once converted to a
string.
A Symbol such as
:" "is not blank, becauseSymbol#blank?isSymbol#empty?, so it reached the escaping step and produced an attributewith no name. The asset helpers symbolize their keys, so an ordinary String
key reached the same place.
[GHSA-68p9-83h6-5wpj]
Mike Dalessio
Fix
strip_tagsto encode"and'in its output.strip_tagsreturns anhtml_safestring, but was not encoding quotationmarks. The method now encodes all five HTML-significant characters (
&,<,>,",'), consistent with the existinghtml_safeconvention.Output used outside HTML, such as in a text template or JSON, now contains
"and&#​39;where it contained"and'.CGI.unescapeHTMLdecodes them.
[GHSA-rq8q-p985-fjq7]
Mike Dalessio
Escape the matched phrase before substituting it into
highlight's:highlighter.A match was copied into each
\1of the highlighter as it appeared inthe sanitized text, which keeps
"and'as they are, so a matchcontaining a quote ended a quoted attribute value such as the
documented
'<a href="search?q=\1">\1</a>'and added attributes ofits own. Each substituted group now goes through
ERB::Util.html_escape_once, so quotes in a match render as"and
&#​39;. Only the numbered placeholders\0to\9are expanded,and a match never replaces the
>that closes a tag.[GHSA-v6rj-xm57-3p59]
Jeremy Daer
Require rails-html-sanitizer 1.7.2 or later.
With the HTML5 sanitizer, Nokogiri before 1.19.5 left
<and>unescaped in attribute values.
highlightandsimple_format, whichedit the sanitized HTML as a string, could then turn markup inside an
attribute value into live elements. rails-html-sanitizer 1.7.2 requires
Loofah 2.25.3, which requires Nokogiri 1.19.5.
[GHSA-2p2f-4rq4-gjwc]
Mike Dalessio
Action Pack
Apply
config.action_dispatch.cookies_same_site_protectionto every sessionstore.
ActionDispatch::Session::CacheStore,MemCacheStoreand third-partystores built on
AbstractStoreor the session mixins sent session cookieswith no
SameSiteattribute. OnlyCookieStoreapplied the configureddefault.
[GHSA-gmj8-hvj3-49mw]
Jean Boussier
Prevent
ActionController::Livestreams from blocking when a full buffer isclosed or aborted.
[GHSA-rwvh-fw6r-pwvp]
Jeremy Daer
Set and extend the
Varyheader for rendered responses according to therequest headers used in format negotiation.
Vary: Acceptwas only added when the request carried a usableAcceptheader. A response to a request without one, negotiated to HTML or
JavaScript, could be stored by a shared cache and served to later clients
that requested a different representation.
Responses now vary on
AcceptandX-Requested-Withwhenever the format isnot given by the URL. XHR requests without
Acceptalso vary onContent-Type, which Rails uses as a legacy format fallback. Whenconfig.action_dispatch.ignore_accept_headeris enabled, responses varyonly on
X-Requested-With.These fields are appended to an existing
Varyvalue without duplicatingfields case-insensitively.
Vary: *remains unchanged.[GHSA-r9jg-fmfx-2gv6]
Jeremy Daer
Skip writing a
CacheStoresession that another request deleted while thisone ran.
A request that loaded a session from
ActionDispatch::Session::CacheStorewrote it back when it finished, even after a concurrent
reset_sessionor aserver-side delete had removed it, so the old session ID worked again.
[GHSA-2586-8ghr-69fj]
Mike Dalessio
Don't write upgraded cookies to a response that skips the session.
Reading a signed or encrypted cookie written under a rotated secret, or in
the format a
:hybridserializer migrates from, writes it back in thecurrent format. That write ignored
request.session_options[:skip], so aresponse that skips the session, such as the Active Storage proxy's
public, cacheable response, could still carry the session cookie in
Set-Cookie. Such a response now leaves the cookie unchanged, and a laterrequest that does not skip the session upgrades it. An application that
skips the session on every request no longer upgrades its signed or
encrypted cookies. Cookies the application sets are still written.
[GHSA-x6mj-8jx9-qhqv]
Mike Dalessio
Detect conflicts between the
ForwardedandX-Forwarded-Forheaders inActionDispatch::RemoteIp.When
ip_spoofing_checkis enabled (the default), requests carrying bothheaders with conflicting client addresses now raise
ActionDispatch::RemoteIp::IpSpoofAttackError.[GHSA-2gff-2mmg-m73p]
Gannon McGibbon, Mike Dalessio
ActionController::Parameters#each_keyreturnsselfwhen given a block.It returned the internal
ActiveSupport::HashWithIndifferentAccess, whichdoes not respond to
permitted?, so passing that return value to massassignment skipped the Strong Parameters check.
each,each_pairandeach_valuealready returnself.Document that
ActionController::Parameters#as_jsonreturns everyparameter, permitted or not, in a hash that mass assignment does not check.
[GHSA-wm3x-v3qw-4jh3]
Mike Dalessio
Active Job
Action Mailer
Action Cable
Active Storage
Preserve committed proxy responses when a storage error interrupts a
streamed download.
[GHSA-4v2w-w6g6-f8f8]
Jeremy Daer
Derive
ActiveStorage::Filename#baseand#extensionfrom the sanitizedfilename.
This prevents null bytes and invalid byte sequences in stored filename
metadata from raising when a blob is opened or represented. Existing blob
records are handled without a data migration.
[GHSA-p2pm-g2h6-7j5j]
Jeremy Daer
Ship an ImageMagick security policy and apply it to every ImageMagick
process MiniMagick spawns.
ImageMagick chooses a coder from the content of the file it is given, and
some coders act on files named inside the image rather than on the image
itself. Active Storage constrained none of them, so an uploaded file could
reach any coder the host's policy allowed, through the ImageMagick analyzer
at attach time, with no variant or
analyzecall in the application.Active Storage now ships a
policy.xmlinActiveStorage::ImageMagick::POLICY_DIRECTORYand prepends that directoryto
MAGICK_CONFIGURE_PATHthroughMiniMagick.cli_env. ImageMagick appliesevery policy file on its search path, so the shipped policy adds to the
host's policy rather than replacing it. A
MAGICK_CONFIGURE_PATHset in theenvironment or in
MiniMagick.cli_env, including by an initializer ordotenv, is kept after the shipped directory.
The shipped policy denies the coders that script ImageMagick (
MSL), reador delete files other than the image (
TEXT,EPHEMERAL), fetch remotereferences (
URL,HTTP,HTTPS,FTP), display to a screen (SHOW,WIN,PLT), or hand the file to Ghostscript (thePS,EPS,EPTandPDFcoders, every alias of them, and thegsdelegate), or reach a filedirectly (
FILE,MPC,XPS,PCL), and it refuses@filenameindirection. The policy applies to every ImageMagick command MiniMagick
runs, not only Active Storage's.
These applications must act:
:mini_magickhas to use mini_magick 5.1or later, which applying the policy requires. With an older mini_magick,
it raises at boot.
the
gsdelegate and the coders it uses in the host'spolicy.xml. Ahost policy that allows a coder overrides the shipped deny.
MiniMagick.cli_envafter it boots, clears theenvironment with
MiniMagick.cli_prefix, or installs its ownMiniMagick::Shellnever receives the shipped policy and has to carryits rules in ImageMagick's system policy. So does one that uses
GraphicsMagick, which does not read ImageMagick policies.
Every other application needs no change. See "ImageMagick Security Policy"
in the Active Storage guide.
[GHSA-f3w6-w445-fwh9]
Mike Dalessio
Enforce the declared content length on Google Cloud Storage direct uploads.
The signed URL now requires an
x-goog-content-length-rangeheader matching the blob'sbyte_size, so Cloud Storage rejects a body of any other size.Browsers send the new header, so a bucket's CORS configuration must list
x-goog-content-length-rangeinresponseHeader, or direct uploads from the browser fail.[GHSA-hfr4-8rjc-97m2]
Mike Dalessio
Sign GCS direct uploads with V2 when
cache_controlis set.V4 signatures did not bind the Content-Type or Content-MD5 headers, so the uploader could
choose the stored Content-Type. Direct-upload URLs with
cache_controlare no longer limitedto 7 days, and the client sends
Cache-Controlunsigned.[GHSA-3w93-6hmw-whh4]
Mike Dalessio
Stop an uploaded filename choosing the extension of the tempfile Active
Storage hands to an external tool.
ActiveStorage::Blob#opennamed its tempfile after the uploaded filename,extension and all. Tools that select a decoder from the extension alone,
such as FFmpeg's AviSynth demuxer on
.avs, therefore took theirinstructions from the uploader. The extension is now kept only when it
denotes the blob's recorded media type, and dropped otherwise.
[GHSA-v924-7rp8-4mxh]
Mike Dalessio
Restrict the formats ffmpeg and ffprobe will open when previewing and
analyzing video and audio.
Active Storage now passes
-format_whitelistbefore the input at everyffmpeg and ffprobe call site, limiting demuxer selection to common audio and
video container formats. Configure the list with
config.active_storage.ffmpeg_allowed_formats, or set it tonilto letffmpeg choose any demuxer it was built with.
Files in other formats, such as MXF, DV, AC3, WavPack, AU, W64, and raw
H.264 or MPEG-1/2 video streams, now fail to preview with
ActiveStorage::PreviewError, and their analysis stores no media metadataand logs a warning. Add their demuxers to the list to keep them.
[GHSA-3f4q-8x5m-76v8]
Mike Dalessio
Action Mailbox
Reject Mailgun inbound emails whose timestamp is more than 2 minutes ahead
of local time.
[GHSA-5957-c7qm-m469]
Mike Dalessio
Action Text
Railties
Guides
Configuration
📅 Schedule: (in timezone America/Los_Angeles)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.