-
-
Notifications
You must be signed in to change notification settings - Fork 236
Expand file tree
/
Copy pathCVE-2024-28121.yml
More file actions
93 lines (75 loc) · 3.53 KB
/
Copy pathCVE-2024-28121.yml
File metadata and controls
93 lines (75 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
---
gem: stimulus_reflex
cve: 2024-28121
ghsa: f78j-4w3g-4q65
url: https://github.com/stimulusreflex/stimulus_reflex/security/advisories/GHSA-f78j-4w3g-4q65
title: StimulusReflex arbitrary method call
date: 2024-03-12
description: |
### 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]:
[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
```
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.
```json
{
"target": "StimulusReflex::Reflex#render_collection",
"args": [
{ "inline": "<% system('[command here]') %>" }
]
}
```
### Patches
Patches are available on [RubyGems] and on [NPM].
[RubyGems]: https://rubygems.org/gems/stimulus_reflex
[NPM]: https://npmjs.org/package/stimulus_reflex
The patched versions are:
- [`3.4.2`](https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.4.2)
- [`3.5.0.rc4`](https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.5.0.rc4)
### Workaround
You can add this guard to mitigate the issue if running an unpatched
version of the library.
1.) Make sure all your reflexes inherit from the `ApplicationReflex`
class
2.) Add this `before_reflex` callback to your `app/reflexes/application_reflex.rb` file:
```ruby
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
```
cvss_v3: 8.8
patched_versions:
- "~> 3.4.2"
- ">= 3.5.0.rc4"
related:
url:
- https://nvd.nist.gov/vuln/detail/CVE-2024-28121
- http://seclists.org/fulldisclosure/2024/Mar/16
- https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.4.2
- https://github.com/stimulusreflex/stimulus_reflex/releases/tag/v3.5.0.rc4
- https://github.com/stimulusreflex/stimulus_reflex/security/advisories/GHSA-f78j-4w3g-4q65
- https://github.com/stimulusreflex/stimulus_reflex/commit/538582d240439aab76066c72335ea92096cd0c7f
- https://github.com/stimulusreflex/stimulus_reflex/commit/d823d7348f9ca42eb6df25574f11974e4f5bc88c
- https://github.com/stimulusreflex/stimulus_reflex/blob/0211cad7d60fe96838587f159d657e44cee51b9b/app/channels/stimulus_reflex/channel.rb#L83
- https://github.com/advisories/GHSA-f78j-4w3g-4q65