Skip to content

Commit cbed83c

Browse files
jasnowRubySec CI
authored and
RubySec CI
committedMar 18, 2024·
Updated advisory posts against rubysec/ruby-advisory-db@359a9f2
1 parent 25ac6cb commit cbed83c

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
layout: advisory
3+
title: 'CVE-2024-28121 (stimulus_reflex): StimulusReflex arbitrary method call'
4+
comments: false
5+
categories:
6+
- stimulus_reflex
7+
advisory:
8+
gem: stimulus_reflex
9+
cve: 2024-28121
10+
ghsa: f78j-4w3g-4q65
11+
url: https://github.com/stimulusreflex/stimulus_reflex/security/advisories/GHSA-f78j-4w3g-4q65
12+
title: StimulusReflex arbitrary method call
13+
date: 2024-03-12
14+
description: |
15+
### Summary
16+
17+
More methods than expected can be called on reflex instances.
18+
Being able to call some of them has security implications.
19+
20+
### Details
21+
22+
To invoke a reflex a websocket message of the following shape is sent:
23+
24+
```json
25+
{
26+
"target": "[class_name]#[method_name]",
27+
"args": []
28+
}
29+
```
30+
31+
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]:
32+
33+
[ref]: https://github.com/stimulusreflex/stimulus_reflex/blob/0211cad7d60fe96838587f159d657e44cee51b9b/app/channels/stimulus_reflex/channel.rb#L83
34+
35+
```ruby
36+
method = reflex.method method_name
37+
required_params = method.parameters.select { |(kind, _)| kind == :req }
38+
optional_params = method.parameters.select { |(kind, _)| kind == :opt }
39+
40+
if arguments.size >= required_params.size && arguments.size <= required_params.size + optional_params.size
41+
reflex.public_send(method_name, *arguments)
42+
end
43+
```
44+
45+
This is problematic as `reflex.method(method_name)` can be more methods than those explicitly specified by the developer in their reflex class. A good example is the `instance_variable_set` method.
46+
47+
```json
48+
{
49+
"target": "StimulusReflex::Reflex#render_collection",
50+
"args": [
51+
{ "inline": "<% system('[command here]') %>" }
52+
]
53+
}
54+
```
55+
56+
### Patches
57+
58+
Patches are available on [RubyGems] and on [NPM].
59+
60+
[RubyGems]: https://rubygems.org/gems/stimulus_reflex
61+
[NPM]: https://npmjs.org/package/stimulus_reflex
62+
63+
The patched versions are:
64+
- [`3.4.2`](https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.4.2)
65+
- [`3.5.0.rc4`](https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.5.0.rc4)
66+
67+
### Workaround
68+
69+
You can add this guard to mitigate the issue if running an unpatched
70+
version of the library.
71+
1.) Make sure all your reflexes inherit from the `ApplicationReflex`
72+
class
73+
2.) Add this `before_reflex` callback to your `app/reflexes/application_reflex.rb` file:
74+
75+
```ruby
76+
class ApplicationReflex < StimulusReflex::Reflex
77+
before_reflex do
78+
ancestors = self.class.ancestors[0..self.class.ancestors.index(StimulusReflex::Reflex) - 1]
79+
allowed = ancestors.any? { |a| a.public_instance_methods(false).any?(method_name.to_sym) }
80+
81+
raise ArgumentError.new("Reflex method '#{method_name}' is not defined on class '#{self.class.name}' or on any of its ancestors") if !allowed
82+
end
83+
end
84+
```
85+
cvss_v3: 8.8
86+
patched_versions:
87+
- "~> 3.4.2"
88+
- ">= 3.5.0.rc4"
89+
related:
90+
url:
91+
- https://nvd.nist.gov/vuln/detail/CVE-2024-28121
92+
- http://seclists.org/fulldisclosure/2024/Mar/16
93+
- https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.4.2
94+
- https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.5.0.rc4
95+
- https://github.com/stimulusreflex/stimulus_reflex/security/advisories/GHSA-f78j-4w3g-4q65
96+
- https://github.com/stimulusreflex/stimulus_reflex/commit/538582d240439aab76066c72335ea92096cd0c7f
97+
- https://github.com/stimulusreflex/stimulus_reflex/commit/d823d7348f9ca42eb6df25574f11974e4f5bc88c
98+
- https://github.com/stimulusreflex/stimulus_reflex/blob/0211cad7d60fe96838587f159d657e44cee51b9b/app/channels/stimulus_reflex/channel.rb#L83
99+
- https://github.com/advisories/GHSA-f78j-4w3g-4q65
100+
---

0 commit comments

Comments
 (0)
Please sign in to comment.