Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2024-28121

CVE-2024-28121: StimulusReflex Privilege Escalation Flaw

CVE-2024-28121 is a privilege escalation vulnerability in StimulusReflex that allows attackers to invoke unintended methods on reflex instances through websocket messages. This article covers technical details, affected versions, security impact, and mitigation strategies.

Published:

CVE-2024-28121 Overview

CVE-2024-28121 affects StimulusReflex, a Ruby library that extends Rails and Stimulus by intercepting user interactions over real-time WebSockets. The vulnerability allows an authenticated attacker to invoke methods on reflex instances beyond those the developer explicitly exposed. Because reflex classes inherit from StimulusReflex::Reflex, an attacker can call ancestor methods such as instance_variable_set through a crafted WebSocket message. This unsafe reflection [CWE-470] leads to compromise of confidentiality, integrity, and availability of the underlying Rails application. Maintainers patched the flaw in versions 3.4.2 and 3.5.0.rc4.

Critical Impact

An authenticated attacker can invoke arbitrary methods on reflex instances via WebSocket messages, enabling manipulation of internal state and potential remote code execution paths in Rails applications.

Affected Products

  • StimulusReflex versions prior to 3.4.2
  • StimulusReflex 3.5.0.pre1 through 3.5.0.pre10
  • StimulusReflex 3.5.0.rc1 through 3.5.0.rc3

Discovery Timeline

  • 2024-03-12 - CVE-2024-28121 published to NVD
  • 2024-03-12 - Full Disclosure mailing list post released
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2024-28121

Vulnerability Analysis

StimulusReflex processes WebSocket messages in the form "target":"[class_name]#[method_name]","args":[]. The server instantiates the class named in class_name as long as it inherits from StimulusReflex::Reflex, then calls method_name on the resulting instance using reflex.method. The framework does not verify that method_name corresponds to a developer-defined action on the reflex class. Any method reachable through Ruby's method resolution order can be invoked, including methods inherited from Object, Kernel, and ActiveSupport extensions. This unsafe reflection classifies as [CWE-470] and reaches over the network, requiring only low-privileged WebSocket access.

Root Cause

The root cause lives in app/channels/stimulus_reflex/channel.rb, where the channel dispatches WebSocket-supplied method names directly to reflex.method(...) without an allowlist. Ruby's Object#method resolves the symbol against the full ancestor chain of the reflex instance, so any inherited method becomes callable. Sensitive methods such as instance_variable_set, send, and public_send become reachable, enabling attackers to mutate internal object state or pivot to further method calls.

Attack Vector

An attacker with WebSocket access to the ActionCable endpoint sends a crafted reflex message referencing a legitimate reflex class but naming an inherited method as the target. The server instantiates the reflex and invokes the method with attacker-supplied arguments. Calling instance_variable_set allows tampering with reflex state, session-linked data, or downstream Rails controller behavior. Depending on how the application handles the mutated state, this may cascade into authorization bypass, information disclosure, or code execution.

ruby
# Patch excerpt from lib/stimulus_reflex/reflex_factory.rb
 class StimulusReflex::ReflexFactory
   attr_reader :channel, :data
 
-  delegate :reflex_name, to: :data
+  delegate :reflex_name, :method_name, to: :data
 
   def initialize(channel, data)
     @channel = channel
     @data = StimulusReflex::ReflexData.new(data)
   end
 
   def call
+    verify_method_name!
     reflex_class.new(channel, reflex_data: data)
   end
 
   private
 
+  def verify_method_name!
+    return if default_reflex?
+
+    argument_error = ArgumentError.new("Reflex method '#{method_name}' is not defined on class '#{reflex_name}' or on any of its ancestors")
+
+    if reflex_method.nil?
+      raise argument_error
+    end
+
+    if !safe_ancestors.include?(reflex_method.owner)
+      raise argument_error
+    end

Source: GitHub commit 538582d. The patch adds verify_method_name!, which requires the resolved method to be owned by a class in an approved ancestor list, blocking calls that resolve to base Ruby or Rails internals.

Detection Methods for CVE-2024-28121

Indicators of Compromise

  • WebSocket messages to the ActionCable endpoint where the target field references methods such as instance_variable_set, send, public_send, eval, or instance_eval.
  • Rails logs showing reflex invocations against method names that do not appear in any application-defined reflex class.
  • Unexpected changes to reflex instance variables or session-linked state immediately following reflex calls.

Detection Strategies

  • Inspect ActionCable channel logs for StimulusReflex::Channel#receive entries and parse the target payload to flag non-allowlisted method names.
  • Add application-level middleware that logs the class and method resolved by each reflex invocation for offline analysis.
  • Correlate WebSocket source IPs invoking suspicious reflex targets with authentication and session telemetry to identify abuse patterns.

Monitoring Recommendations

  • Forward Rails and ActionCable logs to a centralized SIEM and build alerts on method names matching Ruby reflection primitives.
  • Monitor upgrade status of the stimulus_reflex gem across all Rails deployments to confirm remediation coverage.
  • Track outbound HTTP calls and file writes originating from Rails workers immediately after reflex invocations to catch post-exploitation activity.

How to Mitigate CVE-2024-28121

Immediate Actions Required

  • Upgrade stimulus_reflex to 3.4.2 or 3.5.0.rc4 or later in every Rails application that uses the gem.
  • Audit application logs for prior reflex invocations that reference methods outside the intended reflex actions.
  • Rotate any secrets or session material that could have been exposed if internal reflex state was manipulated.

Patch Information

The fix ships in StimulusReflex v3.4.2 and StimulusReflex v3.5.0.rc4. The change introduces verify_method_name! in StimulusReflex::ReflexFactory, which resolves the requested method and rejects any call whose method owner is not in the safe_ancestors list. See the GitHub Security Advisory GHSA-f78j-4w3g-4q65 for the full advisory.

Workarounds

  • If upgrading is not immediately possible, override reflex dispatch to enforce an explicit allowlist of method names per reflex class.
  • Restrict WebSocket access to authenticated users only and apply strict rate limiting on the ActionCable endpoint.
  • Review each reflex class and remove or refactor any inherited methods that could produce dangerous side effects when invoked externally.
bash
# Update the gem to a patched version
bundle update stimulus_reflex --conservative

# Verify the installed version is 3.4.2 or newer
bundle info stimulus_reflex | grep -i version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.