Possible DoS vulnerability in Active Support safe_constantize
Published: November 04, 2026
SECURITY IDENTIFIERS
- GHSA: GHSA-8474-xrp6-wh69
- Vendor Advisory: https://github.com/rails/rails/security/advisories/GHSA-8474-xrp6-wh69
GEM
FRAMEWORK
SEVERITY
CVSS v3.x: 7.5 (High)
PATCHED VERSIONS
~> 8.0.5, >= 8.0.5.2
>= 8.1.4.1
DESCRIPTION
Impact
When constant lookup raises LoadError,
ActiveSupport::Inflector#safe_constantize (and String#safe_constantize)
builds a regular expression from the requested constant name without escaping
it, so a caller that passes untrusted input lets the attacker choose the
source of a pattern that the application compiles. Crafted patterns can
trigger defects in Ruby's regular expression compiler, possibly leading to a
crash of the server process, and repeated requests could keep the application
unavailable.
Action Cable passes the channel value of each subscribe command to
safe_constantize before any channel lookup, so in the default configuration
an unauthenticated client of the Action Cable endpoint can reach this code.
Details
The check that decides whether safe_constantize returns nil or re-raises
the LoadError now matches the first segment of the constant name against the
error message as a literal string, and no longer compiles a regular
expression. It returns the same result as before for constant names that
contain no regular expression syntax.
Affected applications
An application is affected if it meets all of these requirements:
- Mounts Action Cable, which a new Rails application does by default at
/cable(config.action_cable.mount_path), or otherwise passes untrusted input tosafe_constantize. - Accepts Action Cable connections from untrusted clients.
ApplicationCable::Connection#connectauthenticates nobody unless the application adds a check.
Workarounds
Applications that do not use Action Cable can set
config.action_cable.mount_path = nil to remove the endpoint. Applications
that use Action Cable can call reject_unauthorized_connection in
ApplicationCable::Connection#connect for unauthenticated clients, which
limits exposure to authenticated users but does not remove it.
Releases
The fixed releases are available at the normal locations.
Patches for those who cannot upgrade at once:
- 8.1: https://github.com/rails/rails/commit/95aa9e416016524956d4904fed96eaed079580bb.patch
- 8.0: https://github.com/rails/rails/commit/210ac22d446c8e2625b091e79256806b836eee20.patch
Versions affected
- activesupport < 8.0.5.2
- activesupport >= 8.1, < 8.1.4.1
Credit
This issue was responsibly reported by Felix Tscheulin (flixt) through HackerOne researcher scheja, and independently by Bucky Wolfe (Igneous), who provided a proof of concept that crashes the server. It was also found by the Anthropic OSS Scanner (ANT-2026-ZUN5KU3Q).
RELATED
- https://rubygems.org/gems/activesupport/versions/8.1.4.1
- https://github.com/rails/rails/releases/tag/v8.1.4.1
- https://rubygems.org/gems/activesupport/versions/8.0.5.2
- https://github.com/rails/rails/releases/tag/v8.0.5.2
- https://github.com/rails/rails/commit/95aa9e416016524956d4904fed96eaed079580bb
- https://github.com/rails/rails/commit/210ac22d446c8e2625b091e79256806b836eee20
- https://github.com/rails/rails/security/advisories/GHSA-8474-xrp6-wh69
