Unsafe Reflection Affecting stimulus_reflex package, versions <3.4.2 >=3.5.0-pre0, <3.5.0-rc4
Threat Intelligence
Do your applications use this vulnerable package?
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applications- Snyk ID SNYK-RUBY-STIMULUSREFLEX-6427214
- published 13 Mar 2024
- disclosed 12 Mar 2024
- credit Félix Martel
Introduced: 12 Mar 2024
CVE-2024-28121 Open this link in a new tabHow to fix?
Upgrade stimulus_reflex
to version 3.4.2, 3.5.0-rc4 or higher.
Overview
stimulus_reflex is an exciting new way to build modern, reactive, real-time apps with Ruby on Rails.
Affected versions of this package are vulnerable to Unsafe Reflection due to the handling of websocket messages that allow specifying a class_name
and method_name
. An attacker can manipulate the server-side behavior and potentially cause denial of service by crafting malicious websocket messages that invoke unintended methods on the server. This is particularly concerning with methods like instance_variable_set
, which can be used to alter instance variables and influence the application's logic in a harmful way. Additionally, methods intended for debugging or interactive sessions, such as remote_byebug
or pry
, can be invoked, leading to further security implications. The vulnerability is exacerbated by the fact that the validation of method calls based on required and optional parameters does not adequately restrict access to sensitive or unintended methods.
Note:
Versions >=3.5.0.rc1 <3.5.0.rc4
contain a render_collection
method on reflexes with a :req
parameter. Calling this method could lead to arbitrary code execution.
Workaround
This can be mitigated by making sure all the reflexes inherit from the ApplicationReflex
class and by adding this before_reflex
callback to the app/reflexes/application_reflex.rb
file:
class ApplicationReflex < StimulusReflex::Reflex
before_reflex do
ancestors = self.class.ancestors[0..self.class.ancestors.index(StimulusReflex::Reflex) - 1]
allowed = ancestors.any? { |a| a.public_instance_methods(false).any?(method_name.to_sym) }
raise ArgumentError.new("Reflex method '#{method_name}' is not defined on class '#{self.class.name}' or on any of its ancestors") if !allowed
end
end